iced v0.13
This commit is contained in:
parent
b7a51c8141
commit
ad297d1ef8
799
Cargo.lock
generated
799
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -8,8 +8,3 @@ members = [
|
||||
"liana-ui",
|
||||
]
|
||||
default-members = ["liana", "lianad", "liana-gui", "liana-ui"]
|
||||
|
||||
[patch.crates-io]
|
||||
iced_style = { git = "https://github.com/edouardparis/iced", branch = "patch-0.12.3"}
|
||||
iced_winit = { git = "https://github.com/edouardparis/iced", branch = "patch-0.12.3"}
|
||||
iced_futures = { git = "https://github.com/edouardparis/iced", branch = "patch-0.12.3"}
|
||||
|
||||
@ -22,8 +22,8 @@ liana-ui = { path = "../liana-ui" }
|
||||
backtrace = "0.3"
|
||||
hex = "0.4.3"
|
||||
|
||||
iced = { version = "0.12.1", default-features = false, features = ["tokio", "svg", "qr_code", "image", "lazy", "wgpu", "advanced"] }
|
||||
iced_runtime = "0.12.1"
|
||||
iced = { version = "0.13.1", default-features = false, features = ["tokio", "svg", "qr_code", "image", "lazy", "wgpu", "advanced"] }
|
||||
iced_runtime = "0.13.1"
|
||||
|
||||
# Used to verify RFC-compliance of an email
|
||||
email_address = "0.2.7"
|
||||
|
||||
@ -15,7 +15,7 @@ use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
||||
use iced::{clipboard, time, Command, Subscription};
|
||||
use iced::{clipboard, time, Subscription, Task};
|
||||
use tokio::runtime::Handle;
|
||||
use tracing::{error, info, warn};
|
||||
|
||||
@ -148,7 +148,7 @@ impl App {
|
||||
daemon: Arc<dyn Daemon + Sync + Send>,
|
||||
data_dir: PathBuf,
|
||||
internal_bitcoind: Option<Bitcoind>,
|
||||
) -> (App, Command<Message>) {
|
||||
) -> (App, Task<Message>) {
|
||||
let mut panels = Panels::new(
|
||||
&cache,
|
||||
wallet.clone(),
|
||||
@ -170,7 +170,7 @@ impl App {
|
||||
)
|
||||
}
|
||||
|
||||
fn set_current_panel(&mut self, menu: Menu) -> Command<Message> {
|
||||
fn set_current_panel(&mut self, menu: Menu) -> Task<Message> {
|
||||
self.panels.current_mut().interrupt();
|
||||
|
||||
match &menu {
|
||||
@ -183,7 +183,7 @@ impl App {
|
||||
}) {
|
||||
self.panels.transactions.preselect(tx);
|
||||
self.panels.current = menu;
|
||||
return Command::none();
|
||||
return Task::none();
|
||||
};
|
||||
}
|
||||
menu::Menu::PsbtPreSelected(txid) => {
|
||||
@ -198,7 +198,7 @@ impl App {
|
||||
}) {
|
||||
self.panels.psbts.preselect(spend_tx);
|
||||
self.panels.current = menu;
|
||||
return Command::none();
|
||||
return Task::none();
|
||||
};
|
||||
}
|
||||
menu::Menu::RefreshCoins(preselected) => {
|
||||
@ -279,14 +279,14 @@ impl App {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update(&mut self, message: Message) -> Command<Message> {
|
||||
pub fn update(&mut self, message: Message) -> Task<Message> {
|
||||
match message {
|
||||
Message::Tick => {
|
||||
let daemon = self.daemon.clone();
|
||||
let datadir_path = self.cache.datadir_path.clone();
|
||||
let network = self.cache.network;
|
||||
let last_poll_at_startup = self.cache.last_poll_at_startup;
|
||||
Command::perform(
|
||||
Task::perform(
|
||||
async move {
|
||||
// we check every 10 second if the daemon poller is alive
|
||||
// or if the access token is not expired.
|
||||
@ -331,11 +331,11 @@ impl App {
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
return Command::batch(commands);
|
||||
return Task::batch(commands);
|
||||
}
|
||||
Err(e) => tracing::error!("Failed to update cache: {}", e),
|
||||
}
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
Message::LoadDaemonConfig(cfg) => {
|
||||
let path = self.config.daemon_config_path.clone().expect(
|
||||
|
||||
@ -2,7 +2,7 @@ use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
use std::{cmp::Ordering, collections::HashSet};
|
||||
|
||||
use iced::Command;
|
||||
use iced::Task;
|
||||
|
||||
use liana_ui::widget::Element;
|
||||
use lianad::commands::CoinStatus;
|
||||
@ -113,7 +113,7 @@ impl State for CoinsPanel {
|
||||
daemon: Arc<dyn Daemon + Sync + Send>,
|
||||
_cache: &Cache,
|
||||
message: Message,
|
||||
) -> Command<Message> {
|
||||
) -> Task<Message> {
|
||||
match message {
|
||||
Message::Coins(res) => match res {
|
||||
Err(e) => self.warning = Some(e),
|
||||
@ -150,18 +150,18 @@ impl State for CoinsPanel {
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
|
||||
fn reload(
|
||||
&mut self,
|
||||
daemon: Arc<dyn Daemon + Sync + Send>,
|
||||
_wallet: Arc<Wallet>,
|
||||
) -> Command<Message> {
|
||||
) -> Task<Message> {
|
||||
let daemon1 = daemon.clone();
|
||||
let daemon2 = daemon.clone();
|
||||
Command::batch(vec![
|
||||
Command::perform(
|
||||
Task::batch(vec![
|
||||
Task::perform(
|
||||
async move {
|
||||
daemon1
|
||||
.list_coins(&[CoinStatus::Unconfirmed, CoinStatus::Confirmed], &[])
|
||||
@ -171,7 +171,7 @@ impl State for CoinsPanel {
|
||||
},
|
||||
Message::Coins,
|
||||
),
|
||||
Command::perform(
|
||||
Task::perform(
|
||||
async move {
|
||||
let coins = daemon2
|
||||
.list_coins(&[CoinStatus::Unconfirmed, CoinStatus::Confirmed], &[])
|
||||
|
||||
@ -3,7 +3,7 @@ use std::{
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
|
||||
use iced::{Command, Subscription};
|
||||
use iced::{Subscription, Task};
|
||||
use liana_ui::{component::modal::Modal, widget::Element};
|
||||
use tokio::task::JoinHandle;
|
||||
|
||||
@ -37,13 +37,13 @@ impl ExportModal {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn launch(&self) -> Command<Message> {
|
||||
Command::perform(get_path(), |m| {
|
||||
pub fn launch(&self) -> Task<Message> {
|
||||
Task::perform(get_path(), |m| {
|
||||
Message::View(view::Message::Export(ExportMessage::Path(m)))
|
||||
})
|
||||
}
|
||||
|
||||
pub fn update(&mut self, message: Message) -> Command<Message> {
|
||||
pub fn update(&mut self, message: Message) -> Task<Message> {
|
||||
if let Message::View(view::Message::Export(m)) = message {
|
||||
match m {
|
||||
ExportMessage::ExportProgress(m) => match m {
|
||||
@ -73,16 +73,16 @@ impl ExportModal {
|
||||
self.path = Some(path);
|
||||
self.start();
|
||||
} else {
|
||||
return Command::perform(async {}, |_| {
|
||||
return Task::perform(async {}, |_| {
|
||||
Message::View(view::Message::Export(ExportMessage::Close))
|
||||
});
|
||||
}
|
||||
}
|
||||
ExportMessage::Close | ExportMessage::Open => { /* unreachable */ }
|
||||
}
|
||||
Command::none()
|
||||
Task::none()
|
||||
} else {
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
}
|
||||
pub fn view<'a>(&'a self, content: Element<'a, view::Message>) -> Element<view::Message> {
|
||||
|
||||
@ -9,7 +9,7 @@ use crate::{
|
||||
Daemon,
|
||||
},
|
||||
};
|
||||
use iced::Command;
|
||||
use iced::Task;
|
||||
use liana_ui::component::form;
|
||||
|
||||
#[derive(Default)]
|
||||
@ -24,7 +24,7 @@ impl LabelsEdited {
|
||||
daemon: Arc<dyn Daemon + Sync + Send>,
|
||||
message: Message,
|
||||
targets: T,
|
||||
) -> Result<Command<Message>, Error> {
|
||||
) -> Result<Task<Message>, Error> {
|
||||
match message {
|
||||
Message::View(view::Message::Label(items, msg)) => match msg {
|
||||
view::LabelMessage::Edited(value) => {
|
||||
@ -64,7 +64,7 @@ impl LabelsEdited {
|
||||
}
|
||||
}
|
||||
}
|
||||
return Ok(Command::perform(
|
||||
return Ok(Task::perform(
|
||||
async move {
|
||||
daemon.update_labels(&updated_labels).await?;
|
||||
Ok(updated_labels_str)
|
||||
@ -88,7 +88,7 @@ impl LabelsEdited {
|
||||
},
|
||||
_ => {}
|
||||
};
|
||||
Ok(Command::none())
|
||||
Ok(Task::none())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -13,7 +13,7 @@ use std::convert::TryInto;
|
||||
use std::sync::Arc;
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
use iced::{Command, Subscription};
|
||||
use iced::{Subscription, Task};
|
||||
use liana::miniscript::bitcoin::{Amount, OutPoint};
|
||||
use liana_ui::widget::*;
|
||||
use lianad::commands::CoinStatus;
|
||||
@ -50,8 +50,8 @@ pub trait State {
|
||||
_daemon: Arc<dyn Daemon + Sync + Send>,
|
||||
_cache: &Cache,
|
||||
_message: Message,
|
||||
) -> Command<Message> {
|
||||
Command::none()
|
||||
) -> Task<Message> {
|
||||
Task::none()
|
||||
}
|
||||
fn subscription(&self) -> Subscription<Message> {
|
||||
Subscription::none()
|
||||
@ -61,14 +61,14 @@ pub trait State {
|
||||
&mut self,
|
||||
_daemon: Arc<dyn Daemon + Sync + Send>,
|
||||
_wallet: Arc<Wallet>,
|
||||
) -> Command<Message> {
|
||||
Command::none()
|
||||
) -> Task<Message> {
|
||||
Task::none()
|
||||
}
|
||||
}
|
||||
|
||||
/// redirect to another state with a message menu
|
||||
pub fn redirect(menu: Menu) -> Command<Message> {
|
||||
Command::perform(async { menu }, |menu| {
|
||||
pub fn redirect(menu: Menu) -> Task<Message> {
|
||||
Task::perform(async { menu }, |menu| {
|
||||
Message::View(view::Message::Menu(menu))
|
||||
})
|
||||
}
|
||||
@ -201,7 +201,7 @@ impl State for Home {
|
||||
daemon: Arc<dyn Daemon + Sync + Send>,
|
||||
cache: &Cache,
|
||||
message: Message,
|
||||
) -> Command<Message> {
|
||||
) -> Task<Message> {
|
||||
match message {
|
||||
Message::Coins(res) => match res {
|
||||
Err(e) => self.warning = Some(e),
|
||||
@ -277,7 +277,7 @@ impl State for Home {
|
||||
}
|
||||
},
|
||||
Message::View(view::Message::SelectPayment(outpoint)) => {
|
||||
return Command::perform(
|
||||
return Task::perform(
|
||||
async move {
|
||||
let tx = daemon.get_history_txs(&[outpoint.txid]).await?.remove(0);
|
||||
Ok((tx, outpoint.vout as usize))
|
||||
@ -318,7 +318,7 @@ impl State for Home {
|
||||
let daemon = daemon.clone();
|
||||
let last_event_date = last.time.unwrap();
|
||||
self.processing = true;
|
||||
return Command::perform(
|
||||
return Task::perform(
|
||||
async move {
|
||||
let last_event_date = last_event_date.timestamp() as u32;
|
||||
let mut limit = HISTORY_EVENT_PAGE_SIZE;
|
||||
@ -359,20 +359,20 @@ impl State for Home {
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
|
||||
fn reload(
|
||||
&mut self,
|
||||
daemon: Arc<dyn Daemon + Sync + Send>,
|
||||
wallet: Arc<Wallet>,
|
||||
) -> Command<Message> {
|
||||
) -> Task<Message> {
|
||||
// If the wallet is syncing, we expect it to finish soon and so better to wait for
|
||||
// updated data before reloading. Besides, if the wallet is syncing, the DB may be
|
||||
// locked if the poller is running and we wouldn't be able to reload data until
|
||||
// syncing completes anyway.
|
||||
if self.sync_status.wallet_is_syncing() {
|
||||
return Command::none();
|
||||
return Task::none();
|
||||
}
|
||||
self.selected_event = None;
|
||||
self.wallet = wallet;
|
||||
@ -383,8 +383,8 @@ impl State for Home {
|
||||
.as_secs()
|
||||
.try_into()
|
||||
.unwrap();
|
||||
Command::batch(vec![
|
||||
Command::perform(
|
||||
Task::batch(vec![
|
||||
Task::perform(
|
||||
async move {
|
||||
let mut payments = daemon
|
||||
.list_confirmed_payments(0, now, HISTORY_EVENT_PAGE_SIZE)
|
||||
@ -397,7 +397,7 @@ impl State for Home {
|
||||
},
|
||||
Message::Payments,
|
||||
),
|
||||
Command::perform(
|
||||
Task::perform(
|
||||
async move {
|
||||
daemon2
|
||||
.list_coins(&[CoinStatus::Unconfirmed, CoinStatus::Confirmed], &[])
|
||||
|
||||
@ -5,7 +5,7 @@ use std::sync::Arc;
|
||||
|
||||
use iced::Subscription;
|
||||
|
||||
use iced::Command;
|
||||
use iced::Task;
|
||||
use liana::{
|
||||
descriptors::LianaPolicy,
|
||||
miniscript::bitcoin::{bip32::Fingerprint, psbt::Psbt, Network, Txid},
|
||||
@ -36,8 +36,8 @@ use crate::{
|
||||
};
|
||||
|
||||
pub trait Action {
|
||||
fn load(&self, _daemon: Arc<dyn Daemon + Sync + Send>) -> Command<Message> {
|
||||
Command::none()
|
||||
fn load(&self, _daemon: Arc<dyn Daemon + Sync + Send>) -> Task<Message> {
|
||||
Task::none()
|
||||
}
|
||||
fn subscription(&self) -> Subscription<Message> {
|
||||
Subscription::none()
|
||||
@ -47,8 +47,8 @@ pub trait Action {
|
||||
_daemon: Arc<dyn Daemon + Sync + Send>,
|
||||
_message: Message,
|
||||
_tx: &mut SpendTx,
|
||||
) -> Command<Message> {
|
||||
Command::none()
|
||||
) -> Task<Message> {
|
||||
Task::none()
|
||||
}
|
||||
fn view<'a>(&'a self, content: Element<'a, view::Message>) -> Element<'a, view::Message>;
|
||||
}
|
||||
@ -120,11 +120,11 @@ impl PsbtState {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn load(&self, daemon: Arc<dyn Daemon + Sync + Send>) -> Command<Message> {
|
||||
pub fn load(&self, daemon: Arc<dyn Daemon + Sync + Send>) -> Task<Message> {
|
||||
if let Some(action) = &self.action {
|
||||
action.as_ref().load(daemon)
|
||||
} else {
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
}
|
||||
|
||||
@ -133,12 +133,12 @@ impl PsbtState {
|
||||
daemon: Arc<dyn Daemon + Sync + Send>,
|
||||
cache: &Cache,
|
||||
message: Message,
|
||||
) -> Command<Message> {
|
||||
) -> Task<Message> {
|
||||
match message {
|
||||
Message::View(view::Message::Spend(view::SpendTxMessage::Cancel)) => {
|
||||
if let Some(PsbtAction::Sign(SignAction { display_modal, .. })) = &mut self.action {
|
||||
*display_modal = false;
|
||||
return Command::none();
|
||||
return Task::none();
|
||||
}
|
||||
|
||||
self.action = None;
|
||||
@ -149,7 +149,7 @@ impl PsbtState {
|
||||
Message::View(view::Message::Spend(view::SpendTxMessage::Sign)) => {
|
||||
if let Some(PsbtAction::Sign(SignAction { display_modal, .. })) = &mut self.action {
|
||||
*display_modal = true;
|
||||
return Command::none();
|
||||
return Task::none();
|
||||
}
|
||||
|
||||
let action = SignAction::new(
|
||||
@ -171,7 +171,7 @@ impl PsbtState {
|
||||
}
|
||||
Message::View(view::Message::Spend(view::SpendTxMessage::Broadcast)) => {
|
||||
let outpoints: Vec<_> = self.tx.coins.keys().cloned().collect();
|
||||
return Command::perform(
|
||||
return Task::perform(
|
||||
async move {
|
||||
daemon
|
||||
.list_coins(&[CoinStatus::Spending], &outpoints)
|
||||
@ -231,7 +231,7 @@ impl PsbtState {
|
||||
}
|
||||
}
|
||||
};
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
|
||||
pub fn view<'a>(&'a self, cache: &'a Cache) -> Element<'a, view::Message> {
|
||||
@ -265,7 +265,7 @@ impl Action for SaveAction {
|
||||
daemon: Arc<dyn Daemon + Sync + Send>,
|
||||
message: Message,
|
||||
tx: &mut SpendTx,
|
||||
) -> Command<Message> {
|
||||
) -> Task<Message> {
|
||||
match message {
|
||||
Message::View(view::Message::Spend(view::SpendTxMessage::Confirm)) => {
|
||||
let daemon = daemon.clone();
|
||||
@ -276,7 +276,7 @@ impl Action for SaveAction {
|
||||
labels.insert(label_item_from_str(item), Some(label.clone()));
|
||||
}
|
||||
}
|
||||
return Command::perform(
|
||||
return Task::perform(
|
||||
async move {
|
||||
daemon.update_spend_tx(&psbt).await?;
|
||||
daemon.update_labels(&labels).await.map_err(|e| e.into())
|
||||
@ -290,7 +290,7 @@ impl Action for SaveAction {
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
fn view<'a>(&'a self, content: Element<'a, view::Message>) -> Element<'a, view::Message> {
|
||||
modal::Modal::new(
|
||||
@ -316,13 +316,13 @@ impl Action for BroadcastAction {
|
||||
daemon: Arc<dyn Daemon + Sync + Send>,
|
||||
message: Message,
|
||||
tx: &mut SpendTx,
|
||||
) -> Command<Message> {
|
||||
) -> Task<Message> {
|
||||
match message {
|
||||
Message::View(view::Message::Spend(view::SpendTxMessage::Confirm)) => {
|
||||
let daemon = daemon.clone();
|
||||
let psbt = tx.psbt.clone();
|
||||
self.error = None;
|
||||
return Command::perform(
|
||||
return Task::perform(
|
||||
async move {
|
||||
daemon
|
||||
.broadcast_spend_tx(&psbt.unsigned_tx.compute_txid())
|
||||
@ -341,7 +341,7 @@ impl Action for BroadcastAction {
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
fn view<'a>(&'a self, content: Element<'a, view::Message>) -> Element<'a, view::Message> {
|
||||
modal::Modal::new(
|
||||
@ -369,13 +369,13 @@ impl Action for DeleteAction {
|
||||
daemon: Arc<dyn Daemon + Sync + Send>,
|
||||
message: Message,
|
||||
tx: &mut SpendTx,
|
||||
) -> Command<Message> {
|
||||
) -> Task<Message> {
|
||||
match message {
|
||||
Message::View(view::Message::Spend(view::SpendTxMessage::Confirm)) => {
|
||||
let daemon = daemon.clone();
|
||||
let psbt = tx.psbt.clone();
|
||||
self.error = None;
|
||||
return Command::perform(
|
||||
return Task::perform(
|
||||
async move {
|
||||
daemon
|
||||
.delete_spend_tx(&psbt.unsigned_tx.compute_txid())
|
||||
@ -391,7 +391,7 @@ impl Action for DeleteAction {
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
fn view<'a>(&'a self, content: Element<'a, view::Message>) -> Element<'a, view::Message> {
|
||||
modal::Modal::new(
|
||||
@ -443,7 +443,7 @@ impl Action for SignAction {
|
||||
daemon: Arc<dyn Daemon + Sync + Send>,
|
||||
message: Message,
|
||||
tx: &mut SpendTx,
|
||||
) -> Command<Message> {
|
||||
) -> Task<Message> {
|
||||
match message {
|
||||
Message::View(view::Message::SelectHardwareWallet(i)) => {
|
||||
if let Some(HardwareWallet::Supported {
|
||||
@ -456,14 +456,14 @@ impl Action for SignAction {
|
||||
self.signing.insert(*fingerprint);
|
||||
let psbt = tx.psbt.clone();
|
||||
let fingerprint = *fingerprint;
|
||||
return Command::perform(
|
||||
return Task::perform(
|
||||
sign_psbt(self.wallet.clone(), device.clone(), psbt),
|
||||
move |res| Message::Signed(fingerprint, res),
|
||||
);
|
||||
}
|
||||
}
|
||||
Message::View(view::Message::Spend(view::SpendTxMessage::SelectHotSigner)) => {
|
||||
return Command::perform(
|
||||
return Task::perform(
|
||||
sign_psbt_with_hot_signer(self.wallet.clone(), tx.psbt.clone()),
|
||||
|(fg, res)| Message::Signed(fg, res),
|
||||
);
|
||||
@ -482,7 +482,7 @@ impl Action for SignAction {
|
||||
let daemon = daemon.clone();
|
||||
merge_signatures(&mut tx.psbt, &psbt);
|
||||
if self.is_saved {
|
||||
return Command::perform(
|
||||
return Task::perform(
|
||||
async move { daemon.update_spend_tx(&psbt).await.map_err(|e| e.into()) },
|
||||
Message::Updated,
|
||||
);
|
||||
@ -495,7 +495,7 @@ impl Action for SignAction {
|
||||
labels.insert(label_item_from_str(item), Some(label.clone()));
|
||||
}
|
||||
}
|
||||
return Command::perform(
|
||||
return Task::perform(
|
||||
async move {
|
||||
daemon.update_spend_tx(&psbt).await?;
|
||||
daemon.update_labels(&labels).await.map_err(|e| e.into())
|
||||
@ -524,7 +524,7 @@ impl Action for SignAction {
|
||||
},
|
||||
_ => {}
|
||||
};
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
fn view<'a>(&'a self, content: Element<'a, view::Message>) -> Element<'a, view::Message> {
|
||||
let content = toast::Manager::new(
|
||||
@ -683,7 +683,7 @@ impl Action for UpdateAction {
|
||||
daemon: Arc<dyn Daemon + Sync + Send>,
|
||||
message: Message,
|
||||
tx: &mut SpendTx,
|
||||
) -> Command<Message> {
|
||||
) -> Task<Message> {
|
||||
match message {
|
||||
Message::Updated(res) => {
|
||||
self.processing = false;
|
||||
@ -715,7 +715,7 @@ impl Action for UpdateAction {
|
||||
self.processing = true;
|
||||
self.error = None;
|
||||
if let Ok(updated) = Psbt::from_str(&self.updated.value) {
|
||||
return Command::perform(
|
||||
return Task::perform(
|
||||
async move { daemon.update_spend_tx(&updated).await.map_err(|e| e.into()) },
|
||||
Message::Updated,
|
||||
);
|
||||
@ -724,7 +724,7 @@ impl Action for UpdateAction {
|
||||
_ => {}
|
||||
}
|
||||
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use std::str::FromStr;
|
||||
use std::sync::Arc;
|
||||
|
||||
use iced::{Command, Subscription};
|
||||
use iced::{Subscription, Task};
|
||||
|
||||
use liana::miniscript::bitcoin::psbt::Psbt;
|
||||
use liana_ui::{
|
||||
@ -76,7 +76,7 @@ impl State for PsbtsPanel {
|
||||
daemon: Arc<dyn Daemon + Sync + Send>,
|
||||
cache: &Cache,
|
||||
message: Message,
|
||||
) -> Command<Message> {
|
||||
) -> Task<Message> {
|
||||
match message {
|
||||
Message::View(view::Message::Reload) | Message::View(view::Message::Close) => {
|
||||
return self.reload(daemon, self.wallet.clone());
|
||||
@ -122,7 +122,7 @@ impl State for PsbtsPanel {
|
||||
}
|
||||
}
|
||||
}
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
|
||||
fn subscription(&self) -> Subscription<Message> {
|
||||
@ -137,12 +137,12 @@ impl State for PsbtsPanel {
|
||||
&mut self,
|
||||
daemon: Arc<dyn Daemon + Sync + Send>,
|
||||
wallet: Arc<Wallet>,
|
||||
) -> Command<Message> {
|
||||
) -> Task<Message> {
|
||||
self.wallet = wallet;
|
||||
self.selected_tx = None;
|
||||
self.import_tx = None;
|
||||
let daemon = daemon.clone();
|
||||
Command::perform(
|
||||
Task::perform(
|
||||
async move {
|
||||
daemon
|
||||
.list_spend_transactions(None)
|
||||
@ -192,7 +192,7 @@ impl ImportPsbtModal {
|
||||
daemon: Arc<dyn Daemon + Sync + Send>,
|
||||
_cache: &Cache,
|
||||
message: Message,
|
||||
) -> Command<Message> {
|
||||
) -> Task<Message> {
|
||||
match message {
|
||||
Message::Updated(res) => {
|
||||
self.processing = false;
|
||||
@ -213,7 +213,7 @@ impl ImportPsbtModal {
|
||||
self.processing = true;
|
||||
self.error = None;
|
||||
let imported = Psbt::from_str(&self.imported.value).expect("Already checked");
|
||||
return Command::perform(
|
||||
return Task::perform(
|
||||
async move {
|
||||
daemon
|
||||
.update_spend_tx(&imported)
|
||||
@ -227,6 +227,6 @@ impl ImportPsbtModal {
|
||||
_ => {}
|
||||
}
|
||||
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@ use std::collections::{HashMap, HashSet};
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
|
||||
use iced::{widget::qr_code, Command, Subscription};
|
||||
use iced::{widget::qr_code, Subscription, Task};
|
||||
use liana::miniscript::bitcoin::{
|
||||
bip32::{ChildNumber, Fingerprint},
|
||||
Address, Network,
|
||||
@ -112,7 +112,7 @@ impl State for ReceivePanel {
|
||||
daemon: Arc<dyn Daemon + Sync + Send>,
|
||||
cache: &Cache,
|
||||
message: Message,
|
||||
) -> Command<Message> {
|
||||
) -> Task<Message> {
|
||||
match message {
|
||||
Message::View(view::Message::Label(_, _)) | Message::LabelsUpdated(_) => {
|
||||
match self.labels_edited.update(
|
||||
@ -123,7 +123,7 @@ impl State for ReceivePanel {
|
||||
Ok(cmd) => cmd,
|
||||
Err(e) => {
|
||||
self.warning = Some(e);
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -136,11 +136,11 @@ impl State for ReceivePanel {
|
||||
}
|
||||
Err(e) => self.warning = Some(e),
|
||||
}
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
Message::View(view::Message::Close) => {
|
||||
self.modal = Modal::None;
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
Message::View(view::Message::Select(i)) => {
|
||||
self.modal = Modal::VerifyAddress(VerifyAddressModal::new(
|
||||
@ -154,11 +154,11 @@ impl State for ReceivePanel {
|
||||
.get(i)
|
||||
.expect("Must be present"),
|
||||
));
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
Message::View(view::Message::Next) => {
|
||||
let daemon = daemon.clone();
|
||||
Command::perform(
|
||||
Task::perform(
|
||||
async move {
|
||||
daemon
|
||||
.get_new_address()
|
||||
@ -178,13 +178,13 @@ impl State for ReceivePanel {
|
||||
self.modal = Modal::ShowQrCode(modal);
|
||||
}
|
||||
}
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
_ => {
|
||||
if let Modal::VerifyAddress(ref mut m) = self.modal {
|
||||
m.update(daemon, cache, message)
|
||||
} else {
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -194,10 +194,10 @@ impl State for ReceivePanel {
|
||||
&mut self,
|
||||
_daemon: Arc<dyn Daemon + Sync + Send>,
|
||||
wallet: Arc<Wallet>,
|
||||
) -> Command<Message> {
|
||||
) -> Task<Message> {
|
||||
self.wallet = wallet;
|
||||
self.addresses = Addresses::default();
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
}
|
||||
|
||||
@ -253,13 +253,13 @@ impl VerifyAddressModal {
|
||||
_daemon: Arc<dyn Daemon + Sync + Send>,
|
||||
_cache: &Cache,
|
||||
message: Message,
|
||||
) -> Command<Message> {
|
||||
) -> Task<Message> {
|
||||
match message {
|
||||
Message::HardwareWallets(msg) => match self.hws.update(msg) {
|
||||
Ok(cmd) => cmd.map(Message::HardwareWallets),
|
||||
Err(e) => {
|
||||
self.warning = Some(e.into());
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
},
|
||||
Message::Verified(fg, res) => {
|
||||
@ -267,7 +267,7 @@ impl VerifyAddressModal {
|
||||
if let Err(e) = res {
|
||||
self.warning = Some(e);
|
||||
}
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
Message::View(view::Message::SelectHardwareWallet(i)) => {
|
||||
if let Some(HardwareWallet::Supported {
|
||||
@ -279,15 +279,15 @@ impl VerifyAddressModal {
|
||||
self.warning = None;
|
||||
self.chosen_hws.insert(*fingerprint);
|
||||
let fg = *fingerprint;
|
||||
Command::perform(
|
||||
Task::perform(
|
||||
verify_address(device.clone(), self.derivation_index),
|
||||
move |res| Message::Verified(fg, res),
|
||||
)
|
||||
} else {
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
}
|
||||
_ => Command::none(),
|
||||
_ => Task::none(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@ use std::collections::HashSet;
|
||||
use std::str::FromStr;
|
||||
use std::sync::Arc;
|
||||
|
||||
use iced::Command;
|
||||
use iced::Task;
|
||||
|
||||
use liana::miniscript::bitcoin::{
|
||||
bip32::{DerivationPath, Fingerprint},
|
||||
@ -101,7 +101,7 @@ impl State for RecoveryPanel {
|
||||
daemon: Arc<dyn Daemon + Sync + Send>,
|
||||
cache: &Cache,
|
||||
message: Message,
|
||||
) -> Command<Message> {
|
||||
) -> Task<Message> {
|
||||
match message {
|
||||
Message::Coins(res) => match res {
|
||||
Err(e) => self.warning = Some(e),
|
||||
@ -153,7 +153,7 @@ impl State for RecoveryPanel {
|
||||
.get(self.selected_path.expect("A path must be selected"))
|
||||
.map(|p| p.sequence);
|
||||
let network = cache.network;
|
||||
return Command::perform(
|
||||
return Task::perform(
|
||||
async move {
|
||||
let psbt = daemon
|
||||
.create_recovery(address, feerate_vb, sequence)
|
||||
@ -192,14 +192,14 @@ impl State for RecoveryPanel {
|
||||
}
|
||||
}
|
||||
};
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
|
||||
fn reload(
|
||||
&mut self,
|
||||
daemon: Arc<dyn Daemon + Sync + Send>,
|
||||
wallet: Arc<Wallet>,
|
||||
) -> Command<Message> {
|
||||
) -> Task<Message> {
|
||||
let daemon = daemon.clone();
|
||||
self.wallet = wallet;
|
||||
self.selected_path = None;
|
||||
@ -207,7 +207,7 @@ impl State for RecoveryPanel {
|
||||
self.feerate = form::Value::default();
|
||||
self.recipient = form::Value::default();
|
||||
self.generated = None;
|
||||
Command::perform(
|
||||
Task::perform(
|
||||
async move {
|
||||
daemon
|
||||
.list_coins(&[CoinStatus::Unconfirmed, CoinStatus::Confirmed], &[])
|
||||
|
||||
@ -5,7 +5,7 @@ use std::str::FromStr;
|
||||
use std::sync::Arc;
|
||||
|
||||
use chrono::{NaiveDate, Utc};
|
||||
use iced::{clipboard, Command};
|
||||
use iced::{clipboard, Task};
|
||||
use tracing::info;
|
||||
|
||||
use liana::miniscript::bitcoin::Network;
|
||||
@ -90,7 +90,7 @@ impl State for BitcoindSettingsState {
|
||||
daemon: Arc<dyn Daemon + Sync + Send>,
|
||||
cache: &Cache,
|
||||
message: Message,
|
||||
) -> Command<Message> {
|
||||
) -> Task<Message> {
|
||||
match message {
|
||||
Message::DaemonConfigLoaded(res) => match res {
|
||||
Ok(()) => {
|
||||
@ -98,7 +98,7 @@ impl State for BitcoindSettingsState {
|
||||
self.warning = None;
|
||||
if let Some(settings) = &mut self.bitcoind_settings {
|
||||
settings.edited(true);
|
||||
return Command::perform(async {}, |_| {
|
||||
return Task::perform(async {}, |_| {
|
||||
Message::View(view::Message::Settings(
|
||||
view::SettingsMessage::EditBitcoindSettings,
|
||||
))
|
||||
@ -106,7 +106,7 @@ impl State for BitcoindSettingsState {
|
||||
}
|
||||
if let Some(settings) = &mut self.electrum_settings {
|
||||
settings.edited(true);
|
||||
return Command::perform(async {}, |_| {
|
||||
return Task::perform(async {}, |_| {
|
||||
Message::View(view::Message::Settings(
|
||||
view::SettingsMessage::EditBitcoindSettings,
|
||||
))
|
||||
@ -158,7 +158,7 @@ impl State for BitcoindSettingsState {
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
|
||||
fn view<'a>(&'a self, cache: &'a Cache) -> Element<'a, view::Message> {
|
||||
@ -303,7 +303,7 @@ impl BitcoindSettings {
|
||||
daemon: Arc<dyn Daemon + Sync + Send>,
|
||||
_cache: &Cache,
|
||||
message: view::SettingsEditMessage,
|
||||
) -> Command<Message> {
|
||||
) -> Task<Message> {
|
||||
match message {
|
||||
view::SettingsEditMessage::Select => {
|
||||
if !self.processing {
|
||||
@ -359,14 +359,14 @@ impl BitcoindSettings {
|
||||
addr: new_addr.unwrap(),
|
||||
}));
|
||||
self.processing = true;
|
||||
return Command::perform(async move { daemon_config }, |cfg| {
|
||||
return Task::perform(async move { daemon_config }, |cfg| {
|
||||
Message::LoadDaemonConfig(Box::new(cfg))
|
||||
});
|
||||
}
|
||||
}
|
||||
view::SettingsEditMessage::Clipboard(text) => return clipboard::write(text),
|
||||
};
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
|
||||
fn view<'a>(&self, cache: &'a Cache, can_edit: bool) -> Element<'a, view::SettingsEditMessage> {
|
||||
@ -441,7 +441,7 @@ impl ElectrumSettings {
|
||||
daemon: Arc<dyn Daemon + Sync + Send>,
|
||||
_cache: &Cache,
|
||||
message: view::SettingsEditMessage,
|
||||
) -> Command<Message> {
|
||||
) -> Task<Message> {
|
||||
match message {
|
||||
view::SettingsEditMessage::Select => {
|
||||
if !self.processing {
|
||||
@ -467,7 +467,7 @@ impl ElectrumSettings {
|
||||
addr: self.addr.value.clone(),
|
||||
}));
|
||||
self.processing = true;
|
||||
return Command::perform(async move { daemon_config }, |cfg| {
|
||||
return Task::perform(async move { daemon_config }, |cfg| {
|
||||
Message::LoadDaemonConfig(Box::new(cfg))
|
||||
});
|
||||
}
|
||||
@ -475,7 +475,7 @@ impl ElectrumSettings {
|
||||
view::SettingsEditMessage::Clipboard(text) => return clipboard::write(text),
|
||||
_ => {}
|
||||
};
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
|
||||
fn view<'a>(&self, cache: &'a Cache, can_edit: bool) -> Element<'a, view::SettingsEditMessage> {
|
||||
@ -537,7 +537,7 @@ impl RescanSetting {
|
||||
daemon: Arc<dyn Daemon + Sync + Send>,
|
||||
cache: &Cache,
|
||||
message: view::SettingsEditMessage,
|
||||
) -> Command<Message> {
|
||||
) -> Task<Message> {
|
||||
match message {
|
||||
view::SettingsEditMessage::FieldEdited(field, value) => {
|
||||
self.invalid_date = false;
|
||||
@ -601,15 +601,15 @@ impl RescanSetting {
|
||||
}
|
||||
} else {
|
||||
self.invalid_date = true;
|
||||
return Command::none();
|
||||
return Task::none();
|
||||
};
|
||||
if t > Utc::now().timestamp() {
|
||||
self.future_date = true;
|
||||
return Command::none();
|
||||
return Task::none();
|
||||
}
|
||||
self.processing = true;
|
||||
info!("Asking daemon to rescan with timestamp: {}", t);
|
||||
return Command::perform(
|
||||
info!("Asking deamon to rescan with timestamp: {}", t);
|
||||
return Task::perform(
|
||||
async move {
|
||||
daemon.start_rescan(t.try_into().expect("t cannot be inferior to 0 otherwise genesis block timestamp is chosen"))
|
||||
.await
|
||||
@ -620,7 +620,7 @@ impl RescanSetting {
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
|
||||
fn view<'a>(&self, cache: &'a Cache, can_edit: bool) -> Element<'a, view::SettingsEditMessage> {
|
||||
|
||||
@ -5,7 +5,7 @@ use std::convert::From;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
|
||||
use iced::Command;
|
||||
use iced::Task;
|
||||
|
||||
use liana_ui::{component::form, widget::Element};
|
||||
|
||||
@ -55,7 +55,7 @@ impl State for SettingsState {
|
||||
daemon: Arc<dyn Daemon + Sync + Send>,
|
||||
cache: &Cache,
|
||||
message: Message,
|
||||
) -> Command<Message> {
|
||||
) -> Task<Message> {
|
||||
match &message {
|
||||
Message::View(view::Message::Settings(view::SettingsMessage::EditBitcoindSettings)) => {
|
||||
self.setting = Some(
|
||||
@ -71,13 +71,13 @@ impl State for SettingsState {
|
||||
self.setting
|
||||
.as_mut()
|
||||
.map(|s| s.reload(daemon, wallet))
|
||||
.unwrap_or_else(Command::none)
|
||||
.unwrap_or_else(Task::none)
|
||||
}
|
||||
Message::View(view::Message::Settings(
|
||||
view::SettingsMessage::EditRemoteBackendSettings,
|
||||
)) => {
|
||||
self.setting = Some(BackendSettingsState::new().into());
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
Message::View(view::Message::Settings(view::SettingsMessage::AboutSection)) => {
|
||||
self.setting = Some(AboutSettingsState::default().into());
|
||||
@ -85,7 +85,7 @@ impl State for SettingsState {
|
||||
self.setting
|
||||
.as_mut()
|
||||
.map(|s| s.reload(daemon, wallet))
|
||||
.unwrap_or_else(Command::none)
|
||||
.unwrap_or_else(Task::none)
|
||||
}
|
||||
Message::View(view::Message::Settings(view::SettingsMessage::EditWalletSettings)) => {
|
||||
self.setting = Some(
|
||||
@ -95,20 +95,20 @@ impl State for SettingsState {
|
||||
self.setting
|
||||
.as_mut()
|
||||
.map(|s| s.reload(daemon, wallet))
|
||||
.unwrap_or_else(Command::none)
|
||||
.unwrap_or_else(Task::none)
|
||||
}
|
||||
Message::WalletUpdated(Ok(wallet)) => {
|
||||
self.wallet = wallet.clone();
|
||||
self.setting
|
||||
.as_mut()
|
||||
.map(|s| s.update(daemon, cache, message))
|
||||
.unwrap_or_else(Command::none)
|
||||
.unwrap_or_else(Task::none)
|
||||
}
|
||||
_ => self
|
||||
.setting
|
||||
.as_mut()
|
||||
.map(|s| s.update(daemon, cache, message))
|
||||
.unwrap_or_else(Command::none),
|
||||
.unwrap_or_else(Task::none),
|
||||
}
|
||||
}
|
||||
|
||||
@ -132,10 +132,10 @@ impl State for SettingsState {
|
||||
&mut self,
|
||||
_daemon: Arc<dyn Daemon + Sync + Send>,
|
||||
wallet: Arc<Wallet>,
|
||||
) -> Command<Message> {
|
||||
) -> Task<Message> {
|
||||
self.setting = None;
|
||||
self.wallet = wallet;
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
}
|
||||
|
||||
@ -161,7 +161,7 @@ impl State for AboutSettingsState {
|
||||
daemon: Arc<dyn Daemon + Sync + Send>,
|
||||
_cache: &Cache,
|
||||
message: Message,
|
||||
) -> Command<Message> {
|
||||
) -> Task<Message> {
|
||||
if let Message::Info(res) = message {
|
||||
match res {
|
||||
Ok(info) => {
|
||||
@ -175,15 +175,15 @@ impl State for AboutSettingsState {
|
||||
}
|
||||
}
|
||||
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
|
||||
fn reload(
|
||||
&mut self,
|
||||
daemon: Arc<dyn Daemon + Sync + Send>,
|
||||
_wallet: Arc<Wallet>,
|
||||
) -> Command<Message> {
|
||||
Command::perform(
|
||||
) -> Task<Message> {
|
||||
Task::perform(
|
||||
async move { daemon.get_info().await.map_err(|e| e.into()) },
|
||||
Message::Info,
|
||||
)
|
||||
@ -231,20 +231,20 @@ impl State for BackendSettingsState {
|
||||
daemon: Arc<dyn Daemon + Sync + Send>,
|
||||
_cache: &Cache,
|
||||
message: Message,
|
||||
) -> Command<Message> {
|
||||
) -> Task<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();
|
||||
return Task::none();
|
||||
}
|
||||
let email = self.email_form.value.clone();
|
||||
self.processing = true;
|
||||
self.success = false;
|
||||
self.warning = None;
|
||||
Command::perform(
|
||||
Task::perform(
|
||||
async move {
|
||||
daemon.send_wallet_invitation(&email).await?;
|
||||
Ok(())
|
||||
@ -262,7 +262,7 @@ impl State for BackendSettingsState {
|
||||
self.email_form.value = email;
|
||||
self.success = false;
|
||||
}
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
},
|
||||
Message::Updated(res) => {
|
||||
@ -274,9 +274,9 @@ impl State for BackendSettingsState {
|
||||
self.warning = Some(e);
|
||||
}
|
||||
}
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
_ => Command::none(),
|
||||
_ => Task::none(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@ use std::convert::From;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
|
||||
use iced::{Command, Subscription};
|
||||
use iced::{Subscription, Task};
|
||||
|
||||
use liana::{
|
||||
descriptors::LianaDescriptor,
|
||||
@ -107,7 +107,7 @@ impl State for WalletSettingsState {
|
||||
daemon: Arc<dyn Daemon + Sync + Send>,
|
||||
cache: &Cache,
|
||||
message: Message,
|
||||
) -> Command<Message> {
|
||||
) -> Task<Message> {
|
||||
match message {
|
||||
Message::WalletUpdated(res) => {
|
||||
self.processing = false;
|
||||
@ -122,7 +122,7 @@ impl State for WalletSettingsState {
|
||||
}
|
||||
Err(e) => self.warning = Some(e),
|
||||
};
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
}
|
||||
Message::View(view::Message::Settings(
|
||||
@ -135,13 +135,13 @@ impl State for WalletSettingsState {
|
||||
{
|
||||
name.value = value;
|
||||
}
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
Message::View(view::Message::Settings(view::SettingsMessage::Save)) => {
|
||||
self.modal = None;
|
||||
self.processing = true;
|
||||
self.updated = false;
|
||||
Command::perform(
|
||||
Task::perform(
|
||||
update_keys_aliases(
|
||||
self.data_dir.clone(),
|
||||
cache.network,
|
||||
@ -157,7 +157,7 @@ impl State for WalletSettingsState {
|
||||
}
|
||||
Message::View(view::Message::Close) => {
|
||||
self.modal = None;
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
Message::View(view::Message::Settings(view::SettingsMessage::RegisterWallet)) => {
|
||||
self.modal = Some(RegisterWalletModal::new(
|
||||
@ -165,13 +165,13 @@ impl State for WalletSettingsState {
|
||||
self.wallet.clone(),
|
||||
cache.network,
|
||||
));
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
_ => self
|
||||
.modal
|
||||
.as_mut()
|
||||
.map(|m| m.update(daemon, cache, message))
|
||||
.unwrap_or_else(Command::none),
|
||||
.unwrap_or_else(Task::none),
|
||||
}
|
||||
}
|
||||
|
||||
@ -179,11 +179,11 @@ impl State for WalletSettingsState {
|
||||
&mut self,
|
||||
daemon: Arc<dyn Daemon + Sync + Send>,
|
||||
wallet: Arc<Wallet>,
|
||||
) -> Command<Message> {
|
||||
) -> Task<Message> {
|
||||
self.descriptor = wallet.main_descriptor.clone();
|
||||
self.keys_aliases = Self::keys_aliases(&wallet);
|
||||
self.wallet = wallet;
|
||||
Command::perform(
|
||||
Task::perform(
|
||||
async move { daemon.get_info().await.map_err(|e| e.into()) },
|
||||
Message::Info,
|
||||
)
|
||||
@ -244,18 +244,18 @@ impl RegisterWalletModal {
|
||||
daemon: Arc<dyn Daemon + Sync + Send>,
|
||||
cache: &Cache,
|
||||
message: Message,
|
||||
) -> Command<Message> {
|
||||
) -> Task<Message> {
|
||||
match message {
|
||||
Message::View(view::Message::Reload) => {
|
||||
self.chosen_hw = None;
|
||||
self.warning = None;
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
Message::HardwareWallets(msg) => match self.hws.update(msg) {
|
||||
Ok(cmd) => cmd.map(Message::HardwareWallets),
|
||||
Err(e) => {
|
||||
self.warning = Some(e.into());
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
},
|
||||
Message::WalletUpdated(res) => {
|
||||
@ -275,7 +275,7 @@ impl RegisterWalletModal {
|
||||
}
|
||||
}
|
||||
}
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
Message::View(view::Message::SelectHardwareWallet(i)) => {
|
||||
if let Some(HardwareWallet::Supported {
|
||||
@ -286,7 +286,7 @@ impl RegisterWalletModal {
|
||||
{
|
||||
self.chosen_hw = Some(i);
|
||||
self.processing = true;
|
||||
Command::perform(
|
||||
Task::perform(
|
||||
register_wallet(
|
||||
self.data_dir.clone(),
|
||||
cache.network,
|
||||
@ -298,10 +298,10 @@ impl RegisterWalletModal {
|
||||
Message::WalletUpdated,
|
||||
)
|
||||
} else {
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
}
|
||||
_ => Command::none(),
|
||||
_ => Task::none(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@ mod step;
|
||||
use std::collections::HashSet;
|
||||
use std::sync::Arc;
|
||||
|
||||
use iced::Command;
|
||||
use iced::Task;
|
||||
|
||||
use liana::miniscript::bitcoin::{Network, OutPoint};
|
||||
use liana_ui::widget::Element;
|
||||
@ -88,7 +88,7 @@ impl State for CreateSpendPanel {
|
||||
daemon: Arc<dyn Daemon + Sync + Send>,
|
||||
cache: &Cache,
|
||||
message: Message,
|
||||
) -> Command<Message> {
|
||||
) -> Task<Message> {
|
||||
if matches!(message, Message::View(view::Message::Close)) {
|
||||
return redirect(Menu::PSBTs);
|
||||
}
|
||||
@ -114,18 +114,18 @@ impl State for CreateSpendPanel {
|
||||
return step.update(daemon, cache, message);
|
||||
}
|
||||
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
|
||||
fn reload(
|
||||
&mut self,
|
||||
daemon: Arc<dyn Daemon + Sync + Send>,
|
||||
_wallet: Arc<Wallet>,
|
||||
) -> Command<Message> {
|
||||
) -> Task<Message> {
|
||||
let daemon1 = daemon.clone();
|
||||
let daemon2 = daemon.clone();
|
||||
Command::batch(vec![
|
||||
Command::perform(
|
||||
Task::batch(vec![
|
||||
Task::perform(
|
||||
async move {
|
||||
daemon1
|
||||
.list_coins(&[CoinStatus::Unconfirmed, CoinStatus::Confirmed], &[])
|
||||
@ -135,7 +135,7 @@ impl State for CreateSpendPanel {
|
||||
},
|
||||
Message::Coins,
|
||||
),
|
||||
Command::perform(
|
||||
Task::perform(
|
||||
async move {
|
||||
let coins = daemon
|
||||
.list_coins(&[CoinStatus::Unconfirmed, CoinStatus::Confirmed], &[])
|
||||
|
||||
@ -6,7 +6,7 @@ use std::{
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
use iced::{Command, Subscription};
|
||||
use iced::{Subscription, Task};
|
||||
use liana::{
|
||||
descriptors::LianaDescriptor,
|
||||
miniscript::bitcoin::{
|
||||
@ -59,7 +59,7 @@ pub trait Step {
|
||||
daemon: Arc<dyn Daemon + Sync + Send>,
|
||||
cache: &Cache,
|
||||
message: Message,
|
||||
) -> Command<Message>;
|
||||
) -> Task<Message>;
|
||||
fn apply(&self, _draft: &mut TransactionDraft) {}
|
||||
fn interrupt(&mut self) {}
|
||||
fn load(&mut self, _draft: &TransactionDraft) {}
|
||||
@ -394,7 +394,7 @@ impl Step for DefineSpend {
|
||||
daemon: Arc<dyn Daemon + Sync + Send>,
|
||||
cache: &Cache,
|
||||
message: Message,
|
||||
) -> Command<Message> {
|
||||
) -> Task<Message> {
|
||||
match message {
|
||||
Message::View(view::Message::CreateSpend(msg)) => {
|
||||
match msg {
|
||||
@ -413,7 +413,7 @@ impl Step for DefineSpend {
|
||||
.as_slice(),
|
||||
self.timelock,
|
||||
);
|
||||
return Command::none();
|
||||
return Task::none();
|
||||
}
|
||||
view::CreateSpendMessage::AddRecipient => {
|
||||
self.recipients.push(Recipient::default());
|
||||
@ -483,7 +483,7 @@ impl Step for DefineSpend {
|
||||
}
|
||||
let feerate_vb = self.feerate.value.parse::<u64>().unwrap_or(0);
|
||||
self.warning = None;
|
||||
return Command::perform(
|
||||
return Task::perform(
|
||||
async move {
|
||||
daemon
|
||||
.create_spend_tx(&inputs, &outputs, feerate_vb, None)
|
||||
@ -535,7 +535,7 @@ impl Step for DefineSpend {
|
||||
Message::Psbt(res) => match res {
|
||||
Ok(psbt) => {
|
||||
self.generated = Some(psbt);
|
||||
return Command::perform(async {}, |_| Message::View(view::Message::Next));
|
||||
return Task::perform(async {}, |_| Message::View(view::Message::Next));
|
||||
}
|
||||
Err(e) => self.warning = Some(e),
|
||||
},
|
||||
@ -577,7 +577,7 @@ impl Step for DefineSpend {
|
||||
},
|
||||
_ => {}
|
||||
};
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
|
||||
fn apply(&self, draft: &mut TransactionDraft) {
|
||||
@ -799,11 +799,11 @@ impl Step for SaveSpend {
|
||||
daemon: Arc<dyn Daemon + Sync + Send>,
|
||||
cache: &Cache,
|
||||
message: Message,
|
||||
) -> Command<Message> {
|
||||
) -> Task<Message> {
|
||||
if let Some((psbt_state, _)) = &mut self.spend {
|
||||
psbt_state.update(daemon, cache, message)
|
||||
} else {
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@ use std::{
|
||||
time::{SystemTime, UNIX_EPOCH},
|
||||
};
|
||||
|
||||
use iced::Command;
|
||||
use iced::Task;
|
||||
use liana::{
|
||||
miniscript::bitcoin::{OutPoint, Txid},
|
||||
spend::{SpendCreationError, MAX_FEERATE},
|
||||
@ -110,7 +110,7 @@ impl State for TransactionsPanel {
|
||||
daemon: Arc<dyn Daemon + Sync + Send>,
|
||||
_cache: &Cache,
|
||||
message: Message,
|
||||
) -> Command<Message> {
|
||||
) -> Task<Message> {
|
||||
match message {
|
||||
Message::HistoryTransactions(res) => match res {
|
||||
Err(e) => self.warning = Some(e),
|
||||
@ -186,9 +186,9 @@ impl State for TransactionsPanel {
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
return Command::perform(
|
||||
return Task::perform(
|
||||
async move {
|
||||
daemon
|
||||
let res = daemon
|
||||
.list_coins(&[CoinStatus::Spending], &outpoints)
|
||||
.await
|
||||
.map(|res| {
|
||||
@ -197,9 +197,10 @@ impl State for TransactionsPanel {
|
||||
.filter_map(|c| c.spend_info.map(|info| info.txid))
|
||||
.collect()
|
||||
})
|
||||
.map_err(|e| e.into())
|
||||
.map_err(|e| e.into());
|
||||
(Box::new(tx), is_cancel, res)
|
||||
},
|
||||
move |res| Message::RbfModal(Box::new(tx), is_cancel, res),
|
||||
|(tx, is_cancel, res)| Message::RbfModal(tx, is_cancel, res),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -230,7 +231,7 @@ impl State for TransactionsPanel {
|
||||
let daemon = daemon.clone();
|
||||
let last_tx_date = last.time.unwrap();
|
||||
self.processing = true;
|
||||
return Command::perform(
|
||||
return Task::perform(
|
||||
async move {
|
||||
let mut limit = HISTORY_EVENT_PAGE_SIZE;
|
||||
let mut txs =
|
||||
@ -282,18 +283,18 @@ impl State for TransactionsPanel {
|
||||
return match &mut self.modal {
|
||||
TransactionsModal::CreateRbf(modal) => modal.update(daemon, _cache, message),
|
||||
TransactionsModal::Export(modal) => modal.update(message),
|
||||
TransactionsModal::None => Command::none(),
|
||||
TransactionsModal::None => Task::none(),
|
||||
};
|
||||
}
|
||||
};
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
|
||||
fn reload(
|
||||
&mut self,
|
||||
daemon: Arc<dyn Daemon + Sync + Send>,
|
||||
_wallet: Arc<Wallet>,
|
||||
) -> Command<Message> {
|
||||
) -> Task<Message> {
|
||||
self.selected_tx = None;
|
||||
let now: u32 = SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
@ -301,7 +302,7 @@ impl State for TransactionsPanel {
|
||||
.as_secs()
|
||||
.try_into()
|
||||
.unwrap();
|
||||
Command::batch(vec![Command::perform(
|
||||
Task::batch(vec![Task::perform(
|
||||
async move {
|
||||
let mut txs = daemon
|
||||
.list_history_txs(0, now, HISTORY_EVENT_PAGE_SIZE)
|
||||
@ -395,7 +396,7 @@ impl CreateRbfModal {
|
||||
daemon: Arc<dyn Daemon + Sync + Send>,
|
||||
_cache: &Cache,
|
||||
message: Message,
|
||||
) -> Command<Message> {
|
||||
) -> Task<Message> {
|
||||
match message {
|
||||
Message::View(view::Message::CreateRbf(view::CreateRbfMessage::FeerateEdited(s))) => {
|
||||
self.warning = None;
|
||||
@ -424,14 +425,14 @@ impl CreateRbfModal {
|
||||
Message::View(view::Message::CreateRbf(view::CreateRbfMessage::Confirm)) => {
|
||||
self.warning = None;
|
||||
self.processing = true;
|
||||
return Command::perform(
|
||||
return Task::perform(
|
||||
rbf(daemon, self.tx.clone(), self.is_cancel, self.feerate_vb),
|
||||
Message::RbfPsbt,
|
||||
);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
fn view<'a>(&'a self, content: Element<'a, view::Message>) -> Element<view::Message> {
|
||||
let modal = Modal::new(
|
||||
|
||||
@ -46,7 +46,7 @@ pub fn coins_view<'a>(
|
||||
},
|
||||
)),
|
||||
)
|
||||
.align_items(Alignment::Center)
|
||||
.align_x(Alignment::Center)
|
||||
.spacing(30)
|
||||
.into()
|
||||
}
|
||||
@ -84,7 +84,7 @@ fn coin_list_view<'a>(
|
||||
// It is not possible to know if a coin is a
|
||||
// change coin or not so for now, From is
|
||||
// enough
|
||||
p1_regular("From").style(color::GREY_3),
|
||||
p1_regular("From").color(color::GREY_3),
|
||||
)
|
||||
.push(p1_regular(label)),
|
||||
)
|
||||
@ -101,7 +101,7 @@ fn coin_list_view<'a>(
|
||||
// It is not possible to know if a coin is a
|
||||
// change coin or not so for now, From is
|
||||
// enough
|
||||
p1_regular("From").style(color::GREY_3),
|
||||
p1_regular("From").color(color::GREY_3),
|
||||
)
|
||||
.push(p1_regular(label)),
|
||||
)
|
||||
@ -123,14 +123,14 @@ fn coin_list_view<'a>(
|
||||
coin_sequence_label(seq, timelock as u32)
|
||||
})
|
||||
.spacing(10)
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.width(Length::Fill),
|
||||
)
|
||||
.push(amount(&coin.amount))
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.spacing(20),
|
||||
)
|
||||
.style(theme::Button::TransparentBorder)
|
||||
.style(theme::button::transparent_border)
|
||||
.padding(10)
|
||||
.on_press(Message::Select(index)),
|
||||
)
|
||||
@ -156,7 +156,7 @@ fn coin_list_view<'a>(
|
||||
if blockheight > b as u32 + timelock as u32 {
|
||||
Some(Container::new(
|
||||
p1_bold("One of the recovery path is available")
|
||||
.style(color::RED),
|
||||
.color(color::RED),
|
||||
))
|
||||
} else {
|
||||
Some(Container::new(p1_bold(format!(
|
||||
@ -174,72 +174,72 @@ fn coin_list_view<'a>(
|
||||
Column::new()
|
||||
.push(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.push(
|
||||
p2_regular("Address label:")
|
||||
.bold()
|
||||
.style(color::GREY_2),
|
||||
.color(color::GREY_2),
|
||||
)
|
||||
.push(if let Some(label) = labels.get(&address) {
|
||||
p2_regular(label).style(color::GREY_2)
|
||||
p2_regular(label).color(color::GREY_2)
|
||||
} else {
|
||||
p2_regular("No label").style(color::GREY_2)
|
||||
p2_regular("No label").color(color::GREY_2)
|
||||
})
|
||||
.spacing(5),
|
||||
)
|
||||
.push(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.push(p2_regular("Address:").bold().style(color::GREY_2))
|
||||
.align_y(Alignment::Center)
|
||||
.push(p2_regular("Address:").bold().color(color::GREY_2))
|
||||
.push(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.push(
|
||||
p2_regular(address.clone())
|
||||
.style(color::GREY_2),
|
||||
.color(color::GREY_2),
|
||||
)
|
||||
.push(
|
||||
Button::new(icon::clipboard_icon())
|
||||
.on_press(Message::Clipboard(
|
||||
address.clone(),
|
||||
))
|
||||
.style(theme::Button::TransparentBorder),
|
||||
.style(theme::button::transparent_border),
|
||||
),
|
||||
)
|
||||
.spacing(5),
|
||||
)
|
||||
.push(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.push(
|
||||
p2_regular("Deposit transaction label:")
|
||||
.bold()
|
||||
.style(color::GREY_2),
|
||||
.color(color::GREY_2),
|
||||
)
|
||||
.push(if let Some(label) = labels.get(&txid) {
|
||||
p2_regular(label).style(color::GREY_2)
|
||||
p2_regular(label).color(color::GREY_2)
|
||||
} else {
|
||||
p2_regular("No label").style(color::GREY_2)
|
||||
p2_regular("No label").color(color::GREY_2)
|
||||
})
|
||||
.spacing(5),
|
||||
)
|
||||
.push(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.push(p2_regular("Outpoint:").bold().style(color::GREY_2))
|
||||
.align_y(Alignment::Center)
|
||||
.push(p2_regular("Outpoint:").bold().color(color::GREY_2))
|
||||
.push(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.push(
|
||||
p2_regular(format!("{}", coin.outpoint))
|
||||
.style(color::GREY_2),
|
||||
.color(color::GREY_2),
|
||||
)
|
||||
.push(
|
||||
Button::new(icon::clipboard_icon())
|
||||
.on_press(Message::Clipboard(
|
||||
coin.outpoint.to_string(),
|
||||
))
|
||||
.style(theme::Button::TransparentBorder),
|
||||
.style(theme::button::transparent_border),
|
||||
),
|
||||
)
|
||||
.spacing(5),
|
||||
@ -247,9 +247,9 @@ fn coin_list_view<'a>(
|
||||
.push_maybe(coin.block_height.map(|b| {
|
||||
Row::new()
|
||||
.push(
|
||||
p2_regular("Block height:").bold().style(color::GREY_2),
|
||||
p2_regular("Block height:").bold().color(color::GREY_2),
|
||||
)
|
||||
.push(p2_regular(format!("{}", b)).style(color::GREY_2))
|
||||
.push(p2_regular(format!("{}", b)).color(color::GREY_2))
|
||||
.spacing(5)
|
||||
})),
|
||||
)
|
||||
@ -257,7 +257,7 @@ fn coin_list_view<'a>(
|
||||
Column::new()
|
||||
.push(
|
||||
Row::new()
|
||||
.push(p2_regular("Spend txid:").bold().style(color::GREY_2))
|
||||
.push(p2_regular("Spend txid:").bold().color(color::GREY_2))
|
||||
.push(p2_regular(format!("{}", info.txid)))
|
||||
.spacing(5),
|
||||
)
|
||||
@ -266,13 +266,13 @@ fn coin_list_view<'a>(
|
||||
.push(
|
||||
p2_regular("Spend block height:")
|
||||
.bold()
|
||||
.style(color::GREY_2),
|
||||
.color(color::GREY_2),
|
||||
)
|
||||
.push(p2_regular(format!("{}", height)))
|
||||
.spacing(5)
|
||||
} else {
|
||||
Row::new().push(
|
||||
p2_regular("Not in a block").bold().style(color::GREY_2),
|
||||
p2_regular("Not in a block").bold().color(color::GREY_2),
|
||||
)
|
||||
})
|
||||
.spacing(5)
|
||||
@ -291,7 +291,7 @@ fn coin_list_view<'a>(
|
||||
None
|
||||
}),
|
||||
)
|
||||
.style(theme::Container::Card(theme::Card::Simple))
|
||||
.style(theme::card::simple)
|
||||
}
|
||||
|
||||
pub fn coin_sequence_label<'a, T: 'a>(seq: u32, timelock: u32) -> Container<'a, T> {
|
||||
@ -301,30 +301,30 @@ pub fn coin_sequence_label<'a, T: 'a>(seq: u32, timelock: u32) -> Container<'a,
|
||||
.spacing(5)
|
||||
.push(icon::clock_icon().width(Length::Fixed(20.0)))
|
||||
.push(p2_regular("Expired"))
|
||||
.align_items(Alignment::Center),
|
||||
.align_y(Alignment::Center),
|
||||
)
|
||||
.padding(10)
|
||||
.style(theme::Container::Pill(theme::Pill::Warning))
|
||||
.style(theme::pill::warning)
|
||||
} else if seq < timelock * 10 / 100 {
|
||||
Container::new(
|
||||
Row::new()
|
||||
.spacing(5)
|
||||
.push(icon::clock_icon().width(Length::Fixed(20.0)))
|
||||
.push(p2_regular(expire_message(seq)))
|
||||
.align_items(Alignment::Center),
|
||||
.align_y(Alignment::Center),
|
||||
)
|
||||
.padding(10)
|
||||
.style(theme::Container::Pill(theme::Pill::Simple))
|
||||
.style(theme::pill::simple)
|
||||
} else {
|
||||
Container::new(
|
||||
Row::new()
|
||||
.spacing(5)
|
||||
.push(icon::clock_icon().width(Length::Fixed(20.0)))
|
||||
.push(p2_regular(expire_message(seq)).style(color::GREY_3))
|
||||
.align_items(Alignment::Center),
|
||||
.push(p2_regular(expire_message(seq)).color(color::GREY_3))
|
||||
.align_y(Alignment::Center),
|
||||
)
|
||||
.padding(10)
|
||||
.style(theme::Container::Pill(theme::Pill::Simple))
|
||||
.style(theme::pill::simple)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -69,13 +69,13 @@ pub fn home_view<'a>(
|
||||
SyncStatus::WalletFullScan => text("Syncing"),
|
||||
_ => text("Checking for new transactions"),
|
||||
}
|
||||
.style(color::GREY_2),
|
||||
.color(color::GREY_2),
|
||||
)
|
||||
.push(spinner::typing_text_carousel(
|
||||
"...",
|
||||
true,
|
||||
Duration::from_millis(2000),
|
||||
|content| text(content).style(color::GREY_2),
|
||||
|content| text(content).color(color::GREY_2),
|
||||
)),
|
||||
)
|
||||
} else {
|
||||
@ -86,9 +86,9 @@ pub fn home_view<'a>(
|
||||
Some(
|
||||
Row::new()
|
||||
.spacing(10)
|
||||
.push(text("+").size(H3_SIZE).style(color::GREY_3))
|
||||
.push(text("+").size(H3_SIZE).color(color::GREY_3))
|
||||
.push(unconfirmed_amount_with_size(unconfirmed_balance, H3_SIZE))
|
||||
.push(text("unconfirmed").size(H3_SIZE).style(color::GREY_3)),
|
||||
.push(text("unconfirmed").size(H3_SIZE).color(color::GREY_3)),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
@ -100,7 +100,7 @@ pub fn home_view<'a>(
|
||||
Container::new(
|
||||
Row::new()
|
||||
.spacing(15)
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.push(
|
||||
h4_regular(format!(
|
||||
"≈ {} left before first recovery path becomes available.",
|
||||
@ -111,20 +111,20 @@ pub fn home_view<'a>(
|
||||
.push(
|
||||
icon::tooltip_icon()
|
||||
.size(20)
|
||||
.style(color::GREY_3)
|
||||
.color(color::GREY_3)
|
||||
.width(Length::Fixed(20.0)),
|
||||
)
|
||||
.width(Length::Fill),
|
||||
)
|
||||
.padding(25)
|
||||
.style(theme::Card::Border)
|
||||
.style(theme::card::border)
|
||||
})
|
||||
} else {
|
||||
Some(
|
||||
Container::new(
|
||||
Row::new()
|
||||
.spacing(15)
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.push(
|
||||
h4_regular(format!(
|
||||
"Recovery path is or will soon be available for {} coin(s).",
|
||||
@ -140,7 +140,7 @@ pub fn home_view<'a>(
|
||||
),
|
||||
)
|
||||
.padding(25)
|
||||
.style(theme::Card::Invalid),
|
||||
.style(theme::card::invalid),
|
||||
)
|
||||
})
|
||||
.push(
|
||||
@ -164,11 +164,11 @@ pub fn home_view<'a>(
|
||||
"See more"
|
||||
})
|
||||
.width(Length::Fill)
|
||||
.horizontal_alignment(alignment::Horizontal::Center),
|
||||
.align_x(alignment::Horizontal::Center),
|
||||
)
|
||||
.width(Length::Fill)
|
||||
.padding(15)
|
||||
.style(theme::Button::TransparentBorder)
|
||||
.style(theme::button::transparent_border)
|
||||
.on_press_maybe(if !processing {
|
||||
Some(Message::Next)
|
||||
} else {
|
||||
@ -176,7 +176,7 @@ pub fn home_view<'a>(
|
||||
}),
|
||||
)
|
||||
.width(Length::Fill)
|
||||
.style(theme::Container::Card(theme::Card::Simple)),
|
||||
.style(theme::card::simple),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
@ -193,7 +193,7 @@ fn event_list_view(event: &Payment) -> Element<'_, Message> {
|
||||
event
|
||||
.address_label
|
||||
.as_ref()
|
||||
.map(|label| p1_regular(format!("address label: {}", label)).style(color::GREY_3))
|
||||
.map(|label| p1_regular(format!("address label: {}", label)).color(color::GREY_3))
|
||||
};
|
||||
if event.kind == PaymentKind::Incoming {
|
||||
if let Some(t) = event.time {
|
||||
@ -297,8 +297,8 @@ pub fn payment_view<'a>(
|
||||
})
|
||||
.push_maybe(tx.fee_amount.map(|fee_amount| {
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.push(h3("Miner fee: ").style(color::GREY_3))
|
||||
.align_y(Alignment::Center)
|
||||
.push(h3("Miner fee: ").color(color::GREY_3))
|
||||
.push(amount_with_size(&fee_amount, H3_SIZE))
|
||||
.push(text(" ").size(H3_SIZE))
|
||||
.push(
|
||||
@ -307,7 +307,7 @@ pub fn payment_view<'a>(
|
||||
fee_amount.to_sat() / tx.tx.vsize() as u64
|
||||
))
|
||||
.size(H4_SIZE)
|
||||
.style(color::GREY_3),
|
||||
.color(color::GREY_3),
|
||||
)
|
||||
}))
|
||||
.push(card::simple(
|
||||
@ -325,11 +325,11 @@ pub fn payment_view<'a>(
|
||||
.push(
|
||||
Row::new()
|
||||
.width(Length::Fill)
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.push(Container::new(text("Txid:").bold()).width(Length::Fill))
|
||||
.push(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.push(Container::new(
|
||||
text(format!("{}", tx.tx.compute_txid())).small(),
|
||||
))
|
||||
@ -338,7 +338,7 @@ pub fn payment_view<'a>(
|
||||
.on_press(Message::Clipboard(
|
||||
tx.tx.compute_txid().to_string(),
|
||||
))
|
||||
.style(theme::Button::TransparentBorder),
|
||||
.style(theme::button::transparent_border),
|
||||
)
|
||||
.width(Length::Shrink),
|
||||
),
|
||||
|
||||
@ -69,7 +69,7 @@ pub fn hw_list_view(
|
||||
kind, pairing_code, ..
|
||||
} => hw::locked_hardware_wallet(kind, pairing_code.as_ref()),
|
||||
})
|
||||
.style(theme::Button::Border)
|
||||
.style(theme::button::container_border)
|
||||
.width(Length::Fill);
|
||||
if !signing {
|
||||
if let HardwareWallet::Supported { registered, .. } = hw {
|
||||
@ -80,7 +80,7 @@ pub fn hw_list_view(
|
||||
}
|
||||
Container::new(bttn)
|
||||
.width(Length::Fill)
|
||||
.style(theme::Container::Card(theme::Card::Simple))
|
||||
.style(theme::card::simple)
|
||||
.into()
|
||||
}
|
||||
|
||||
@ -137,14 +137,14 @@ pub fn hw_list_view_for_registration(
|
||||
kind, pairing_code, ..
|
||||
} => hw::locked_hardware_wallet(kind, pairing_code.as_ref()),
|
||||
})
|
||||
.style(theme::Button::Border)
|
||||
.style(theme::button::container_border)
|
||||
.width(Length::Fill);
|
||||
if !processing && hw.is_supported() {
|
||||
bttn = bttn.on_press(Message::SelectHardwareWallet(i));
|
||||
}
|
||||
Container::new(bttn)
|
||||
.width(Length::Fill)
|
||||
.style(theme::Container::Card(theme::Card::Simple))
|
||||
.style(theme::card::simple)
|
||||
.into()
|
||||
}
|
||||
|
||||
@ -222,13 +222,13 @@ pub fn hw_list_view_verify_address(
|
||||
),
|
||||
};
|
||||
let mut bttn = Button::new(content)
|
||||
.style(theme::Button::Border)
|
||||
.style(theme::button::container_border)
|
||||
.width(Length::Fill);
|
||||
if selectable && hw.is_supported() {
|
||||
bttn = bttn.on_press(Message::SelectHardwareWallet(i));
|
||||
}
|
||||
Container::new(bttn)
|
||||
.width(Length::Fill)
|
||||
.style(theme::Container::Card(theme::Card::Simple))
|
||||
.style(theme::card::simple)
|
||||
.into()
|
||||
}
|
||||
|
||||
@ -28,7 +28,7 @@ pub fn label_editable(
|
||||
)
|
||||
)
|
||||
.spacing(5)
|
||||
.align_items(Alignment::Center),
|
||||
.align_y(Alignment::Center),
|
||||
)
|
||||
.into();
|
||||
}
|
||||
@ -61,7 +61,7 @@ pub fn label_editing(
|
||||
button::secondary(None, "Cancel").on_press(view::message::LabelMessage::Cancel)
|
||||
)
|
||||
.spacing(5)
|
||||
.align_items(Alignment::Center),
|
||||
.align_y(Alignment::Center),
|
||||
)
|
||||
.into();
|
||||
e.map(move |msg| view::Message::Label(labelled.clone(), msg))
|
||||
|
||||
@ -38,7 +38,7 @@ use crate::app::{cache::Cache, error::Error, menu::Menu};
|
||||
fn menu_green_bar<'a, T: 'a>() -> Container<'a, T> {
|
||||
Container::new(Space::with_width(Length::Fixed(2.0)))
|
||||
.height(Length::Fixed(50.0))
|
||||
.style(theme::Container::Custom(color::GREEN))
|
||||
.style(theme::container::custom(color::GREEN))
|
||||
}
|
||||
|
||||
pub fn sidebar<'a>(menu: &Menu, cache: &'a Cache) -> Container<'a, Message> {
|
||||
@ -77,7 +77,7 @@ pub fn sidebar<'a>(menu: &Menu, cache: &'a Cache) -> Container<'a, Message> {
|
||||
)
|
||||
} else {
|
||||
row!(button::menu(Some(coins_icon()), "Coins")
|
||||
.style(theme::Button::Menu(false))
|
||||
.style(theme::button::menu)
|
||||
.on_press(Message::Menu(Menu::Coins))
|
||||
.width(iced::Length::Fill))
|
||||
};
|
||||
@ -161,14 +161,14 @@ pub fn sidebar<'a>(menu: &Menu, cache: &'a Cache) -> Container<'a, Message> {
|
||||
.push_maybe(cache.rescan_progress.map(|p| {
|
||||
Container::new(text(format!(" Rescan...{:.2}% ", p * 100.0)))
|
||||
.padding(5)
|
||||
.style(theme::Pill::Simple)
|
||||
.style(theme::pill::simple)
|
||||
}))
|
||||
.push(settings_button),
|
||||
)
|
||||
.height(Length::Shrink),
|
||||
),
|
||||
)
|
||||
.style(theme::Container::Foreground)
|
||||
.style(theme::container::foreground)
|
||||
}
|
||||
|
||||
pub fn dashboard<'a, T: Into<Element<'a, Message>>>(
|
||||
@ -194,9 +194,8 @@ pub fn dashboard<'a, T: Into<Element<'a, Message>>>(
|
||||
.max_width(1500),
|
||||
Space::with_width(Length::FillPortion(1)),
|
||||
)))
|
||||
.center_x()
|
||||
.style(theme::Container::Background)
|
||||
.width(Length::Fill)
|
||||
.center_x(Length::Fill)
|
||||
.style(theme::container::background)
|
||||
.height(Length::Fill),
|
||||
)
|
||||
.width(Length::FillPortion(10)),
|
||||
@ -226,11 +225,11 @@ pub fn modal<'a, T: Into<Element<'a, Message>>, F: Into<Element<'a, Message>>>(
|
||||
} else {
|
||||
Column::new().width(Length::Fill)
|
||||
})
|
||||
.align_items(iced::Alignment::Center)
|
||||
.align_y(iced::Alignment::Center)
|
||||
.push(button::secondary(Some(cross_icon()), "Close").on_press(Message::Close)),
|
||||
)
|
||||
.padding(10)
|
||||
.style(theme::Container::Background),
|
||||
.style(theme::container::background),
|
||||
)
|
||||
.push(modal_section(Container::new(scrollable(content))))
|
||||
.push_maybe(fixed_footer)
|
||||
@ -241,8 +240,8 @@ pub fn modal<'a, T: Into<Element<'a, Message>>, F: Into<Element<'a, Message>>>(
|
||||
|
||||
fn modal_section<'a, T: 'a>(menu: Container<'a, T>) -> Container<'a, T> {
|
||||
Container::new(menu.max_width(1500))
|
||||
.style(theme::Container::Background)
|
||||
.center_x()
|
||||
.style(theme::container::background)
|
||||
.center_x(Length::Fill)
|
||||
.width(Length::Fill)
|
||||
.height(Length::Fill)
|
||||
}
|
||||
|
||||
@ -56,7 +56,7 @@ pub fn psbt_view<'a>(
|
||||
.spacing(20)
|
||||
.push(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.spacing(10)
|
||||
.push(Container::new(h3("PSBT")).width(Length::Fill))
|
||||
.push_maybe(if !tx.sigs.recovery_paths().is_empty() {
|
||||
@ -198,14 +198,14 @@ pub fn broadcast_action<'a>(
|
||||
Row::new()
|
||||
.padding([0, 30])
|
||||
.spacing(5)
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.push(text(txid.to_string()))
|
||||
.push(
|
||||
Button::new(
|
||||
icon::clipboard_icon().style(color::GREY_3),
|
||||
icon::clipboard_icon().color(color::GREY_3),
|
||||
)
|
||||
.on_press(Message::Clipboard(txid.to_string()))
|
||||
.style(theme::Button::TransparentBorder),
|
||||
.style(theme::button::transparent_border),
|
||||
),
|
||||
)
|
||||
},
|
||||
@ -233,7 +233,7 @@ pub fn delete_action<'a>(warning: Option<&Error>, deleted: bool) -> Element<'a,
|
||||
card::simple(
|
||||
Column::new()
|
||||
.spacing(20)
|
||||
.align_items(Alignment::Center)
|
||||
.align_x(Alignment::Center)
|
||||
.push(text("Successfully deleted this transaction."))
|
||||
.push(button::secondary(None, "Go back to PSBTs").on_press(Message::Close)),
|
||||
)
|
||||
@ -296,8 +296,8 @@ pub fn spend_header<'a>(
|
||||
})
|
||||
.push(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.push(h3("Miner fee: ").style(color::GREY_3))
|
||||
.align_y(Alignment::Center)
|
||||
.push(h3("Miner fee: ").color(color::GREY_3))
|
||||
.push_maybe(if tx.fee_amount.is_none() {
|
||||
Some(text("Missing information about transaction inputs"))
|
||||
} else {
|
||||
@ -308,7 +308,7 @@ pub fn spend_header<'a>(
|
||||
.push_maybe(tx.min_feerate_vb().map(|rate| {
|
||||
text(format!("(~{} sats/vbyte)", &rate))
|
||||
.size(H4_SIZE)
|
||||
.style(color::GREY_3)
|
||||
.color(color::GREY_3)
|
||||
})),
|
||||
),
|
||||
)
|
||||
@ -331,7 +331,7 @@ pub fn spend_overview_view<'a>(
|
||||
.spacing(10)
|
||||
.push(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.push(text("PSBT").bold().width(Length::Fill))
|
||||
.push(
|
||||
Row::new()
|
||||
@ -351,28 +351,28 @@ pub fn spend_overview_view<'a>(
|
||||
.on_press(Message::Spend(SpendTxMessage::EditPsbt)),
|
||||
),
|
||||
)
|
||||
.align_items(Alignment::Center),
|
||||
.align_y(Alignment::Center),
|
||||
)
|
||||
.push(
|
||||
Row::new()
|
||||
.push(p1_bold("Tx ID").width(Length::Fill))
|
||||
.push(
|
||||
p2_regular(tx.psbt.unsigned_tx.compute_txid().to_string())
|
||||
.style(color::GREY_3),
|
||||
.color(color::GREY_3),
|
||||
)
|
||||
.push(
|
||||
Button::new(icon::clipboard_icon().style(color::GREY_3))
|
||||
Button::new(icon::clipboard_icon().color(color::GREY_3))
|
||||
.on_press(Message::Clipboard(
|
||||
tx.psbt.unsigned_tx.compute_txid().to_string(),
|
||||
))
|
||||
.style(theme::Button::TransparentBorder),
|
||||
.style(theme::button::transparent_border),
|
||||
)
|
||||
.align_items(Alignment::Center),
|
||||
.align_y(Alignment::Center),
|
||||
),
|
||||
)
|
||||
.push(signatures(tx, desc_info, key_aliases)),
|
||||
)
|
||||
.style(theme::Container::Card(theme::Card::Simple)),
|
||||
.style(theme::card::simple),
|
||||
)
|
||||
.push_maybe(if tx.status == SpendStatus::Pending {
|
||||
Some(
|
||||
@ -391,7 +391,7 @@ pub fn spend_overview_view<'a>(
|
||||
.width(Length::Fixed(150.0)),
|
||||
)
|
||||
})
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.spacing(20),
|
||||
)
|
||||
} else {
|
||||
@ -411,11 +411,11 @@ pub fn signatures<'a>(
|
||||
scrollable(
|
||||
Row::new()
|
||||
.spacing(5)
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.spacing(10)
|
||||
.push(p1_bold("Status"))
|
||||
.push(icon::circle_check_icon().style(color::GREEN))
|
||||
.push(text("Ready").bold().style(color::GREEN))
|
||||
.push(icon::circle_check_icon().color(color::GREEN))
|
||||
.push(text("Ready").bold().color(color::GREEN))
|
||||
.push(text(" signed by"))
|
||||
.push(sigs.signed_pubkeys.keys().fold(
|
||||
Row::new().spacing(5),
|
||||
@ -425,22 +425,22 @@ pub fn signatures<'a>(
|
||||
tooltip::Tooltip::new(
|
||||
Container::new(text(alias))
|
||||
.padding(10)
|
||||
.style(theme::Container::Pill(theme::Pill::Simple)),
|
||||
.style(theme::pill::simple),
|
||||
text(value.to_string()),
|
||||
tooltip::Position::Bottom,
|
||||
)
|
||||
.style(theme::Container::Card(theme::Card::Simple)),
|
||||
.style(theme::card::simple),
|
||||
)
|
||||
} else {
|
||||
Container::new(text(value.to_string()))
|
||||
.padding(10)
|
||||
.style(theme::Container::Pill(theme::Pill::Simple))
|
||||
.style(theme::pill::simple)
|
||||
})
|
||||
},
|
||||
)),
|
||||
)
|
||||
.direction(scrollable::Direction::Horizontal(
|
||||
scrollable::Properties::new().width(2).scroller_width(2),
|
||||
scrollable::Scrollbar::new().width(2).scroller_width(2),
|
||||
)),
|
||||
)
|
||||
.padding(15)
|
||||
@ -449,42 +449,42 @@ pub fn signatures<'a>(
|
||||
move || {
|
||||
Button::new(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.spacing(20)
|
||||
.push(p1_bold("Status"))
|
||||
.push(
|
||||
Row::new()
|
||||
.spacing(5)
|
||||
.align_items(Alignment::Center)
|
||||
.push(icon::circle_cross_icon().style(color::RED))
|
||||
.push(text("Not ready").style(color::RED))
|
||||
.align_y(Alignment::Center)
|
||||
.push(icon::circle_cross_icon().color(color::RED))
|
||||
.push(text("Not ready").color(color::RED))
|
||||
.width(Length::Fill),
|
||||
)
|
||||
.push(icon::collapse_icon()),
|
||||
)
|
||||
.padding(15)
|
||||
.width(Length::Fill)
|
||||
.style(theme::Button::TransparentBorder)
|
||||
.style(theme::button::transparent_border)
|
||||
},
|
||||
move || {
|
||||
Button::new(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.spacing(20)
|
||||
.push(p1_bold("Status"))
|
||||
.push(
|
||||
Row::new()
|
||||
.spacing(5)
|
||||
.align_items(Alignment::Center)
|
||||
.push(icon::circle_cross_icon().style(color::RED))
|
||||
.push(text("Not ready").style(color::RED))
|
||||
.align_y(Alignment::Center)
|
||||
.push(icon::circle_cross_icon().color(color::RED))
|
||||
.push(text("Not ready").color(color::RED))
|
||||
.width(Length::Fill),
|
||||
)
|
||||
.push(icon::collapsed_icon()),
|
||||
)
|
||||
.padding(15)
|
||||
.width(Length::Fill)
|
||||
.style(theme::Button::TransparentBorder)
|
||||
.style(theme::button::transparent_border)
|
||||
},
|
||||
move || {
|
||||
Into::<Element<'a, Message>>::into(
|
||||
@ -521,16 +521,16 @@ fn container_from_fg(
|
||||
tooltip::Tooltip::new(
|
||||
Container::new(text(alias))
|
||||
.padding(10)
|
||||
.style(theme::Container::Pill(theme::Pill::Simple)),
|
||||
.style(theme::pill::simple),
|
||||
liana_ui::widget::Text::new(fg.to_string()),
|
||||
tooltip::Position::Bottom,
|
||||
)
|
||||
.style(theme::Container::Card(theme::Card::Simple)),
|
||||
.style(theme::card::simple),
|
||||
)
|
||||
} else {
|
||||
Container::new(text(fg.to_string()))
|
||||
.padding(10)
|
||||
.style(theme::Container::Pill(theme::Pill::Simple))
|
||||
.style(theme::pill::simple)
|
||||
}
|
||||
}
|
||||
|
||||
@ -565,13 +565,13 @@ pub fn path_view<'a>(
|
||||
|
||||
scrollable(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.push(
|
||||
Row::new()
|
||||
.push(if missing_signatures == 0 {
|
||||
icon::circle_check_icon().style(color::GREEN)
|
||||
icon::circle_check_icon().color(color::GREEN)
|
||||
} else {
|
||||
icon::circle_cross_icon().style(color::GREY_3)
|
||||
icon::circle_cross_icon().color(color::GREY_3)
|
||||
})
|
||||
.push(Space::with_width(Length::Fixed(20.0))),
|
||||
)
|
||||
@ -587,17 +587,17 @@ pub fn path_view<'a>(
|
||||
" from "
|
||||
}
|
||||
))
|
||||
.style(color::GREY_3),
|
||||
.color(color::GREY_3),
|
||||
)
|
||||
.push_maybe(row_unsigned)
|
||||
.push_maybe(
|
||||
(!sigs.signed_pubkeys.is_empty())
|
||||
.then_some(p1_regular(", already signed by ").style(color::GREY_3)),
|
||||
.then_some(p1_regular(", already signed by ").color(color::GREY_3)),
|
||||
)
|
||||
.push(row_signed),
|
||||
)
|
||||
.direction(scrollable::Direction::Horizontal(
|
||||
scrollable::Properties::new().width(2).scroller_width(2),
|
||||
scrollable::Scrollbar::new().width(2).scroller_width(2),
|
||||
))
|
||||
.into()
|
||||
}
|
||||
@ -612,7 +612,7 @@ pub fn inputs_view<'a>(
|
||||
move || {
|
||||
Button::new(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.push(
|
||||
h4_bold(format!(
|
||||
"{} coin{} spent",
|
||||
@ -625,12 +625,12 @@ pub fn inputs_view<'a>(
|
||||
)
|
||||
.padding(20)
|
||||
.width(Length::Fill)
|
||||
.style(theme::Button::TransparentBorder)
|
||||
.style(theme::button::transparent_border)
|
||||
},
|
||||
move || {
|
||||
Button::new(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.push(
|
||||
h4_bold(format!(
|
||||
"{} coin{} spent",
|
||||
@ -643,7 +643,7 @@ pub fn inputs_view<'a>(
|
||||
)
|
||||
.padding(20)
|
||||
.width(Length::Fill)
|
||||
.style(theme::Button::TransparentBorder)
|
||||
.style(theme::button::transparent_border)
|
||||
},
|
||||
move || {
|
||||
tx.input
|
||||
@ -662,7 +662,7 @@ pub fn inputs_view<'a>(
|
||||
.into()
|
||||
},
|
||||
))
|
||||
.style(theme::Container::Card(theme::Card::Simple))
|
||||
.style(theme::card::simple)
|
||||
.into()
|
||||
}
|
||||
|
||||
@ -695,7 +695,7 @@ pub fn outputs_view<'a>(
|
||||
move || {
|
||||
Button::new(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.push(
|
||||
h4_bold(format!(
|
||||
"{} payment{}",
|
||||
@ -708,12 +708,12 @@ pub fn outputs_view<'a>(
|
||||
)
|
||||
.padding(20)
|
||||
.width(Length::Fill)
|
||||
.style(theme::Button::TransparentBorder)
|
||||
.style(theme::button::transparent_border)
|
||||
},
|
||||
move || {
|
||||
Button::new(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.push(
|
||||
h4_bold(format!(
|
||||
"{} payment{}",
|
||||
@ -726,7 +726,7 @@ pub fn outputs_view<'a>(
|
||||
)
|
||||
.padding(20)
|
||||
.width(Length::Fill)
|
||||
.style(theme::Button::TransparentBorder)
|
||||
.style(theme::button::transparent_border)
|
||||
},
|
||||
move || {
|
||||
tx.output
|
||||
@ -756,12 +756,14 @@ pub fn outputs_view<'a>(
|
||||
.into()
|
||||
},
|
||||
))
|
||||
.style(theme::Container::Card(theme::Card::Simple))
|
||||
.style(theme::card::simple)
|
||||
} else {
|
||||
Container::new(h4_bold("0 payment"))
|
||||
.padding(20)
|
||||
.width(Length::Fill)
|
||||
.style(theme::Container::Card(theme::Card::Simple))
|
||||
Container::new(h4_bold("0 payment").style(|t| {
|
||||
theme::text::custom(t.colors.buttons.transparent_border.active.text)
|
||||
}))
|
||||
.padding(20)
|
||||
.width(Length::Fill)
|
||||
.style(theme::card::simple)
|
||||
}
|
||||
})
|
||||
.push_maybe(
|
||||
@ -775,24 +777,24 @@ pub fn outputs_view<'a>(
|
||||
move || {
|
||||
Button::new(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.push(h4_bold("Change").width(Length::Fill))
|
||||
.push(icon::collapse_icon()),
|
||||
)
|
||||
.padding(20)
|
||||
.width(Length::Fill)
|
||||
.style(theme::Button::TransparentBorder)
|
||||
.style(theme::button::transparent_border)
|
||||
},
|
||||
move || {
|
||||
Button::new(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.push(h4_bold("Change").width(Length::Fill))
|
||||
.push(icon::collapsed_icon()),
|
||||
)
|
||||
.padding(20)
|
||||
.width(Length::Fill)
|
||||
.style(theme::Button::TransparentBorder)
|
||||
.style(theme::button::transparent_border)
|
||||
},
|
||||
move || {
|
||||
tx.output
|
||||
@ -808,7 +810,7 @@ pub fn outputs_view<'a>(
|
||||
.into()
|
||||
},
|
||||
))
|
||||
.style(theme::Container::Card(theme::Card::Simple)),
|
||||
.style(theme::card::simple),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
@ -829,7 +831,7 @@ fn input_view<'a>(
|
||||
.push(
|
||||
Row::new()
|
||||
.spacing(5)
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.push(
|
||||
Container::new(if let Some(label) = labels_editing.get(&outpoint) {
|
||||
label::label_editing(vec![outpoint.clone()], label, text::P1_SIZE)
|
||||
@ -848,47 +850,47 @@ fn input_view<'a>(
|
||||
Column::new()
|
||||
.push(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.spacing(5)
|
||||
.push(p1_bold("Outpoint:").style(color::GREY_3))
|
||||
.push(p2_regular(outpoint.clone()).style(color::GREY_3))
|
||||
.push(p1_bold("Outpoint:").color(color::GREY_3))
|
||||
.push(p2_regular(outpoint.clone()).color(color::GREY_3))
|
||||
.push(
|
||||
Button::new(icon::clipboard_icon().style(color::GREY_3))
|
||||
Button::new(icon::clipboard_icon().color(color::GREY_3))
|
||||
.on_press(Message::Clipboard(outpoint.clone()))
|
||||
.style(theme::Button::TransparentBorder),
|
||||
.style(theme::button::transparent_border),
|
||||
),
|
||||
)
|
||||
.push_maybe(coin.map(|c| {
|
||||
let addr = c.address.to_string();
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.width(Length::Fill)
|
||||
.push(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.width(Length::Fill)
|
||||
.spacing(5)
|
||||
.push(p1_bold("Address:").style(color::GREY_3))
|
||||
.push(p2_regular(addr.clone()).style(color::GREY_3))
|
||||
.push(p1_bold("Address:").color(color::GREY_3))
|
||||
.push(p2_regular(addr.clone()).color(color::GREY_3))
|
||||
.push(
|
||||
Button::new(icon::clipboard_icon().style(color::GREY_3))
|
||||
Button::new(icon::clipboard_icon().color(color::GREY_3))
|
||||
.on_press(Message::Clipboard(addr))
|
||||
.style(theme::Button::TransparentBorder),
|
||||
.style(theme::button::transparent_border),
|
||||
),
|
||||
)
|
||||
}))
|
||||
.push_maybe(coin.and_then(|c| {
|
||||
labels.get(&c.address.to_string()).map(|label| {
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.width(Length::Fill)
|
||||
.push(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.width(Length::Fill)
|
||||
.spacing(5)
|
||||
.push(p1_bold("Address label:").style(color::GREY_3))
|
||||
.push(p2_regular(label).style(color::GREY_3)),
|
||||
.push(p1_bold("Address label:").color(color::GREY_3))
|
||||
.push(p2_regular(label).color(color::GREY_3)),
|
||||
)
|
||||
})
|
||||
})),
|
||||
@ -927,7 +929,7 @@ fn payment_view<'a>(
|
||||
.push(
|
||||
Row::new()
|
||||
.spacing(5)
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.push(
|
||||
Container::new(if let Some(label) = labels_editing.get(&outpoint) {
|
||||
label::label_editing(change_labels, label, text::P1_SIZE)
|
||||
@ -942,33 +944,33 @@ fn payment_view<'a>(
|
||||
Column::new()
|
||||
.push(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.width(Length::Fill)
|
||||
.push(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.width(Length::Fill)
|
||||
.spacing(5)
|
||||
.push(p1_bold("Address:").style(color::GREY_3))
|
||||
.push(p2_regular(addr.clone()).style(color::GREY_3))
|
||||
.push(p1_bold("Address:").color(color::GREY_3))
|
||||
.push(p2_regular(addr.clone()).color(color::GREY_3))
|
||||
.push(
|
||||
Button::new(icon::clipboard_icon().style(color::GREY_3))
|
||||
Button::new(icon::clipboard_icon().color(color::GREY_3))
|
||||
.on_press(Message::Clipboard(addr.clone()))
|
||||
.style(theme::Button::TransparentBorder),
|
||||
.style(theme::button::transparent_border),
|
||||
),
|
||||
),
|
||||
)
|
||||
.push_maybe(labels.get(&addr).map(|label| {
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.width(Length::Fill)
|
||||
.push(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.width(Length::Fill)
|
||||
.spacing(5)
|
||||
.push(p1_bold("Address label:").style(color::GREY_3))
|
||||
.push(p2_regular(label).style(color::GREY_3)),
|
||||
.push(p1_bold("Address label:").color(color::GREY_3))
|
||||
.push(p2_regular(label).color(color::GREY_3)),
|
||||
)
|
||||
}))
|
||||
}))
|
||||
@ -989,19 +991,19 @@ fn change_view(output: &TxOut, network: Network) -> Element<Message> {
|
||||
)
|
||||
.push(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.width(Length::Fill)
|
||||
.push(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.width(Length::Fill)
|
||||
.spacing(5)
|
||||
.push(p1_bold("Address:").style(color::GREY_3))
|
||||
.push(p2_regular(addr.clone()).style(color::GREY_3))
|
||||
.push(p1_bold("Address:").color(color::GREY_3))
|
||||
.push(p2_regular(addr.clone()).color(color::GREY_3))
|
||||
.push(
|
||||
Button::new(icon::clipboard_icon().style(color::GREY_3))
|
||||
Button::new(icon::clipboard_icon().color(color::GREY_3))
|
||||
.on_press(Message::Clipboard(addr))
|
||||
.style(theme::Button::TransparentBorder),
|
||||
.style(theme::button::transparent_border),
|
||||
),
|
||||
),
|
||||
)
|
||||
@ -1051,14 +1053,14 @@ pub fn sign_action<'a>(
|
||||
})
|
||||
.on_press(Message::Spend(SpendTxMessage::SelectHotSigner))
|
||||
.padding(10)
|
||||
.style(theme::Button::Border)
|
||||
.style(theme::button::container_border)
|
||||
.width(Length::Fill)
|
||||
}))
|
||||
.width(Length::Fill),
|
||||
)
|
||||
.spacing(20)
|
||||
.width(Length::Fill)
|
||||
.align_items(Alignment::Center),
|
||||
.align_x(Alignment::Center),
|
||||
))
|
||||
.width(Length::Fixed(500.0))
|
||||
.into()
|
||||
@ -1086,7 +1088,7 @@ pub fn sign_action_toasts<'a>(
|
||||
kind,
|
||||
version.as_ref(),
|
||||
fingerprint,
|
||||
alias.as_ref(),
|
||||
alias.as_ref().map(|x| x.as_str()),
|
||||
)
|
||||
.max_width(400.0)
|
||||
.into(),
|
||||
@ -1131,7 +1133,7 @@ pub fn update_spend_view<'a>(
|
||||
button::secondary(Some(icon::clipboard_icon()), "Copy")
|
||||
.on_press(Message::Clipboard(psbt)),
|
||||
)
|
||||
.align_items(Alignment::Center),
|
||||
.align_y(Alignment::Center),
|
||||
)
|
||||
.push(separation().width(Length::Fill))
|
||||
.push(
|
||||
@ -1166,11 +1168,11 @@ pub fn update_spend_success_view<'a>() -> Element<'a, Message> {
|
||||
Column::new()
|
||||
.push(
|
||||
card::simple(Container::new(
|
||||
text("Spend transaction is updated").style(color::GREEN),
|
||||
text("Spend transaction is updated").color(color::GREEN),
|
||||
))
|
||||
.padding(50),
|
||||
)
|
||||
.width(Length::Fixed(400.0))
|
||||
.align_items(Alignment::Center)
|
||||
.align_x(Alignment::Center)
|
||||
.into()
|
||||
}
|
||||
|
||||
@ -51,10 +51,10 @@ pub fn import_psbt_view<'a>(
|
||||
pub fn import_psbt_success_view<'a>() -> Element<'a, Message> {
|
||||
Column::new()
|
||||
.push(
|
||||
card::simple(Container::new(text("PSBT is imported").style(color::GREEN))).padding(50),
|
||||
card::simple(Container::new(text("PSBT is imported").color(color::GREEN))).padding(50),
|
||||
)
|
||||
.width(Length::Fixed(400.0))
|
||||
.align_items(Alignment::Center)
|
||||
.align_x(Alignment::Center)
|
||||
.into()
|
||||
}
|
||||
|
||||
@ -62,7 +62,7 @@ pub fn psbts_view(spend_txs: &[SpendTx]) -> Element<'_, Message> {
|
||||
Column::new()
|
||||
.push(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.spacing(10)
|
||||
.push(Container::new(h3("PSBTs")).width(Length::Fill))
|
||||
.push(
|
||||
@ -84,7 +84,7 @@ pub fn psbts_view(spend_txs: &[SpendTx]) -> Element<'_, Message> {
|
||||
}),
|
||||
),
|
||||
)
|
||||
.align_items(Alignment::Center)
|
||||
.align_x(Alignment::Center)
|
||||
.spacing(25)
|
||||
.into()
|
||||
}
|
||||
@ -107,7 +107,7 @@ fn spend_tx_list_view(i: usize, tx: &SpendTx) -> Element<'_, Message> {
|
||||
Container::new(
|
||||
Row::new()
|
||||
.spacing(5)
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.push(
|
||||
p2_regular(format!(
|
||||
"{}/{}",
|
||||
@ -118,9 +118,9 @@ fn spend_tx_list_view(i: usize, tx: &SpendTx) -> Element<'_, Message> {
|
||||
},
|
||||
sigs.threshold
|
||||
))
|
||||
.style(color::GREY_3),
|
||||
.color(color::GREY_3),
|
||||
)
|
||||
.push(icon::key_icon().style(color::GREY_3)),
|
||||
.push(icon::key_icon().color(color::GREY_3)),
|
||||
)
|
||||
})
|
||||
.push_maybe(
|
||||
@ -129,7 +129,7 @@ fn spend_tx_list_view(i: usize, tx: &SpendTx) -> Element<'_, Message> {
|
||||
.map(p1_regular),
|
||||
)
|
||||
.spacing(10)
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.width(Length::Fill),
|
||||
)
|
||||
.push_maybe(if tx.is_batch() {
|
||||
@ -145,7 +145,7 @@ fn spend_tx_list_view(i: usize, tx: &SpendTx) -> Element<'_, Message> {
|
||||
})
|
||||
.push(
|
||||
Column::new()
|
||||
.align_items(Alignment::End)
|
||||
.align_x(Alignment::End)
|
||||
.push(if !tx.is_send_to_self() {
|
||||
Container::new(amount(&tx.spend_amount))
|
||||
} else {
|
||||
@ -154,13 +154,13 @@ fn spend_tx_list_view(i: usize, tx: &SpendTx) -> Element<'_, Message> {
|
||||
.push_maybe(tx.fee_amount.map(|fee| amount_with_size(&fee, P2_SIZE)))
|
||||
.width(Length::Fixed(140.0)),
|
||||
)
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.spacing(20),
|
||||
)
|
||||
.padding(10)
|
||||
.on_press(Message::Select(i))
|
||||
.style(theme::Button::TransparentBorder),
|
||||
.style(theme::button::transparent_border),
|
||||
)
|
||||
.style(theme::Container::Card(theme::Card::Simple))
|
||||
.style(theme::card::simple)
|
||||
.into()
|
||||
}
|
||||
|
||||
@ -42,7 +42,7 @@ pub fn receive<'a>(
|
||||
Column::new()
|
||||
.push(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.push(Container::new(h3("Receive")).width(Length::Fill))
|
||||
.push(
|
||||
button::secondary(Some(icon::plus_icon()), "Generate address")
|
||||
@ -85,7 +85,7 @@ pub fn receive<'a>(
|
||||
.push(
|
||||
p2_regular(addr)
|
||||
.small()
|
||||
.style(color::GREY_3),
|
||||
.color(color::GREY_3),
|
||||
)
|
||||
// Space between the address and the scrollbar
|
||||
.push(Space::with_height(
|
||||
@ -93,7 +93,7 @@ pub fn receive<'a>(
|
||||
)),
|
||||
)
|
||||
.direction(scrollable::Direction::Horizontal(
|
||||
scrollable::Properties::new()
|
||||
scrollable::Scrollbar::new()
|
||||
.width(2)
|
||||
.scroller_width(2),
|
||||
)),
|
||||
@ -102,12 +102,12 @@ pub fn receive<'a>(
|
||||
)
|
||||
.push(
|
||||
Button::new(
|
||||
icon::clipboard_icon().style(color::GREY_3),
|
||||
icon::clipboard_icon().color(color::GREY_3),
|
||||
)
|
||||
.on_press(Message::Clipboard(address.to_string()))
|
||||
.style(theme::Button::TransparentBorder),
|
||||
.style(theme::button::transparent_border),
|
||||
)
|
||||
.align_items(Alignment::Center),
|
||||
.align_y(Alignment::Center),
|
||||
)
|
||||
.push(
|
||||
Row::new()
|
||||
@ -153,14 +153,14 @@ pub fn verify_address_modal<'a>(
|
||||
.push(
|
||||
Row::new()
|
||||
.width(Length::Fill)
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.push(
|
||||
Container::new(text("Address:").bold())
|
||||
.width(Length::Fill),
|
||||
)
|
||||
.push(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.push(Container::new(
|
||||
text(address.to_string()).small(),
|
||||
))
|
||||
@ -169,7 +169,7 @@ pub fn verify_address_modal<'a>(
|
||||
.on_press(Message::Clipboard(
|
||||
address.to_string(),
|
||||
))
|
||||
.style(theme::Button::TransparentBorder),
|
||||
.style(theme::button::transparent_border),
|
||||
)
|
||||
.width(Length::Shrink),
|
||||
),
|
||||
@ -177,7 +177,7 @@ pub fn verify_address_modal<'a>(
|
||||
.push(
|
||||
Row::new()
|
||||
.width(Length::Fill)
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.push(
|
||||
Container::new(text("Derivation index:").bold())
|
||||
.width(Length::Fill),
|
||||
@ -211,7 +211,7 @@ pub fn verify_address_modal<'a>(
|
||||
)
|
||||
.spacing(20)
|
||||
.width(Length::Fill)
|
||||
.align_items(Alignment::Center),
|
||||
.align_x(Alignment::Center),
|
||||
))
|
||||
.width(Length::Fill)
|
||||
.max_width(750)
|
||||
@ -225,17 +225,12 @@ pub fn qr_modal<'a>(qr: &'a qr_code::Data, address: &'a String) -> Element<'a, M
|
||||
.push(Space::with_width(Length::Fill))
|
||||
.push(
|
||||
Container::new(QRCode::<liana_ui::theme::Theme>::new(qr).cell_size(8))
|
||||
.padding(10)
|
||||
.style(theme::Container::QrCode),
|
||||
.padding(10),
|
||||
)
|
||||
.push(Space::with_width(Length::Fill)),
|
||||
)
|
||||
.push(Space::with_height(Length::Fixed(15.0)))
|
||||
.push(
|
||||
Container::new(text(address).size(15))
|
||||
.width(Length::Fill)
|
||||
.center_x(),
|
||||
)
|
||||
.push(Container::new(text(address).size(15)).center_x(Length::Fill))
|
||||
.width(Length::Fill)
|
||||
.max_width(400)
|
||||
.into()
|
||||
|
||||
@ -44,16 +44,16 @@ pub fn recovery<'a>(
|
||||
.push(
|
||||
Row::new()
|
||||
.spacing(10)
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.push(
|
||||
Button::new(text("Settings").size(30).bold())
|
||||
.style(theme::Button::Transparent)
|
||||
.style(theme::button::transparent)
|
||||
.on_press(Message::Menu(Menu::Settings)),
|
||||
)
|
||||
.push(icon::chevron_right().size(30))
|
||||
.push(
|
||||
Button::new(text("Recovery").size(30).bold())
|
||||
.style(theme::Button::Transparent)
|
||||
.style(theme::button::transparent)
|
||||
.on_press(Message::Menu(Menu::Recovery)),
|
||||
),
|
||||
)
|
||||
@ -61,7 +61,7 @@ pub fn recovery<'a>(
|
||||
.push(
|
||||
Row::new()
|
||||
.spacing(20)
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.push(text("Destination").bold())
|
||||
.push(
|
||||
Container::new(
|
||||
@ -102,7 +102,7 @@ pub fn recovery<'a>(
|
||||
)))
|
||||
.push(Column::with_children(recovery_paths).spacing(20)),
|
||||
)
|
||||
.style(theme::Container::Card(theme::Card::Simple))
|
||||
.style(theme::card::simple)
|
||||
.padding(20)
|
||||
})
|
||||
.push_maybe(if no_recovery_paths {
|
||||
@ -126,7 +126,7 @@ pub fn recovery<'a>(
|
||||
},
|
||||
)
|
||||
.spacing(20)
|
||||
.align_items(Alignment::Center),
|
||||
.align_y(Alignment::Center),
|
||||
)
|
||||
})
|
||||
.spacing(20),
|
||||
@ -151,7 +151,7 @@ pub fn recovery_path_view<'a>(
|
||||
Column::new()
|
||||
.push(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.spacing(10)
|
||||
.push(
|
||||
text(format!(
|
||||
@ -162,23 +162,23 @@ pub fn recovery_path_view<'a>(
|
||||
.bold(),
|
||||
)
|
||||
.push(origins.iter().fold(
|
||||
Row::new().align_items(Alignment::Center).spacing(5),
|
||||
Row::new().align_y(Alignment::Center).spacing(5),
|
||||
|row, (fg, _)| {
|
||||
row.push(if let Some(alias) = key_aliases.get(fg) {
|
||||
Container::new(
|
||||
tooltip::Tooltip::new(
|
||||
Container::new(text(alias))
|
||||
.padding(5)
|
||||
.style(theme::Container::Pill(theme::Pill::Simple)),
|
||||
.style(theme::pill::simple),
|
||||
liana_ui::widget::Text::new(fg.to_string()),
|
||||
tooltip::Position::Bottom,
|
||||
)
|
||||
.style(theme::Container::Card(theme::Card::Simple)),
|
||||
.style(theme::card::simple),
|
||||
)
|
||||
} else {
|
||||
Container::new(text(fg.to_string()))
|
||||
.padding(5)
|
||||
.style(theme::Container::Pill(theme::Pill::Simple))
|
||||
.style(theme::pill::simple)
|
||||
})
|
||||
},
|
||||
)),
|
||||
@ -197,7 +197,7 @@ pub fn recovery_path_view<'a>(
|
||||
.spacing(5),
|
||||
)
|
||||
.width(Length::Fill)
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.spacing(20)
|
||||
.into()
|
||||
}
|
||||
|
||||
@ -46,99 +46,99 @@ pub fn list(cache: &Cache, is_remote_backend: bool) -> Element<Message> {
|
||||
.width(Length::Fill)
|
||||
.push(
|
||||
Button::new(text("Settings").size(30).bold())
|
||||
.style(theme::Button::Transparent)
|
||||
.style(theme::button::transparent)
|
||||
.on_press(Message::Menu(Menu::Settings)))
|
||||
.push(
|
||||
if !is_remote_backend {
|
||||
Container::new(
|
||||
Button::new(
|
||||
Row::new()
|
||||
.push(badge::Badge::new(icon::bitcoin_icon()))
|
||||
.push(badge::badge(icon::bitcoin_icon()))
|
||||
.push(text("Node").bold())
|
||||
.padding(10)
|
||||
.spacing(20)
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.width(Length::Fill),
|
||||
)
|
||||
.width(Length::Fill)
|
||||
.style(theme::Button::TransparentBorder)
|
||||
.style(theme::button::transparent_border)
|
||||
.on_press(Message::Settings(SettingsMessage::EditBitcoindSettings))
|
||||
)
|
||||
.width(Length::Fill)
|
||||
.style(theme::Container::Card(theme::Card::Simple))
|
||||
.style(theme::card::simple)
|
||||
} else {
|
||||
Container::new(
|
||||
Button::new(
|
||||
Row::new()
|
||||
.push(badge::Badge::new(icon::bitcoin_icon()))
|
||||
.push(badge::badge(icon::bitcoin_icon()))
|
||||
.push(text("Backend").bold())
|
||||
.padding(10)
|
||||
.spacing(20)
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.width(Length::Fill),
|
||||
)
|
||||
.width(Length::Fill)
|
||||
.style(theme::Button::TransparentBorder)
|
||||
.style(theme::button::transparent_border)
|
||||
.on_press(Message::Settings(SettingsMessage::EditRemoteBackendSettings))
|
||||
)
|
||||
.width(Length::Fill)
|
||||
.style(theme::Container::Card(theme::Card::Simple))
|
||||
.style(theme::card::simple)
|
||||
}
|
||||
)
|
||||
.push(
|
||||
Container::new(
|
||||
Button::new(
|
||||
Row::new()
|
||||
.push(badge::Badge::new(icon::wallet_icon()))
|
||||
.push(badge::badge(icon::wallet_icon()))
|
||||
.push(text("Wallet").bold())
|
||||
.padding(10)
|
||||
.spacing(20)
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.width(Length::Fill),
|
||||
)
|
||||
.width(Length::Fill)
|
||||
.style(theme::Button::TransparentBorder)
|
||||
.style(theme::button::transparent_border)
|
||||
.on_press(Message::Settings(SettingsMessage::EditWalletSettings))
|
||||
)
|
||||
.width(Length::Fill)
|
||||
.style(theme::Container::Card(theme::Card::Simple))
|
||||
.style(theme::card::simple)
|
||||
)
|
||||
.push(
|
||||
Container::new(
|
||||
Button::new(
|
||||
Row::new()
|
||||
.push(badge::Badge::new(icon::recovery_icon()))
|
||||
.push(badge::badge(icon::recovery_icon()))
|
||||
.push(text("Recovery").bold())
|
||||
.push(tooltip("In case of loss of the main key, the recovery key can move the funds after a certain time."))
|
||||
.padding(10)
|
||||
.spacing(20)
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.width(Length::Fill),
|
||||
)
|
||||
.width(Length::Fill)
|
||||
.style(theme::Button::TransparentBorder)
|
||||
.style(theme::button::transparent_border)
|
||||
.on_press(Message::Menu(Menu::Recovery))
|
||||
)
|
||||
.width(Length::Fill)
|
||||
.style(theme::Container::Card(theme::Card::Simple))
|
||||
.style(theme::card::simple)
|
||||
)
|
||||
.push(
|
||||
Container::new(
|
||||
Button::new(
|
||||
Row::new()
|
||||
.push(badge::Badge::new(icon::tooltip_icon()))
|
||||
.push(badge::badge(icon::tooltip_icon()))
|
||||
.push(text("About").bold())
|
||||
.padding(10)
|
||||
.spacing(20)
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.width(Length::Fill),
|
||||
)
|
||||
.width(Length::Fill)
|
||||
.style(theme::Button::TransparentBorder)
|
||||
.style(theme::button::transparent_border)
|
||||
.on_press(Message::Settings(SettingsMessage::AboutSection))
|
||||
)
|
||||
.width(Length::Fill)
|
||||
.style(theme::Container::Card(theme::Card::Simple))
|
||||
.style(theme::card::simple)
|
||||
)
|
||||
)
|
||||
}
|
||||
@ -156,16 +156,16 @@ pub fn bitcoind_settings<'a>(
|
||||
.push(
|
||||
Row::new()
|
||||
.spacing(10)
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.push(
|
||||
Button::new(text("Settings").size(30).bold())
|
||||
.style(theme::Button::Transparent)
|
||||
.style(theme::button::transparent)
|
||||
.on_press(Message::Menu(Menu::Settings)),
|
||||
)
|
||||
.push(icon::chevron_right().size(30))
|
||||
.push(
|
||||
Button::new(text("Node").size(30).bold())
|
||||
.style(theme::Button::Transparent)
|
||||
.style(theme::button::transparent)
|
||||
.on_press(Message::Settings(SettingsMessage::EditBitcoindSettings)),
|
||||
),
|
||||
)
|
||||
@ -187,16 +187,16 @@ pub fn about_section<'a>(
|
||||
.push(
|
||||
Row::new()
|
||||
.spacing(10)
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.push(
|
||||
Button::new(text("Settings").size(30).bold())
|
||||
.style(theme::Button::Transparent)
|
||||
.style(theme::button::transparent)
|
||||
.on_press(Message::Menu(Menu::Settings)),
|
||||
)
|
||||
.push(icon::chevron_right().size(30))
|
||||
.push(
|
||||
Button::new(text("About").size(30).bold())
|
||||
.style(theme::Button::Transparent)
|
||||
.style(theme::button::transparent)
|
||||
.on_press(Message::Settings(SettingsMessage::AboutSection)),
|
||||
),
|
||||
)
|
||||
@ -205,11 +205,11 @@ pub fn about_section<'a>(
|
||||
Column::new()
|
||||
.push(
|
||||
Row::new()
|
||||
.push(badge::Badge::new(icon::tooltip_icon()))
|
||||
.push(badge::badge(icon::tooltip_icon()))
|
||||
.push(text("Version").bold())
|
||||
.padding(10)
|
||||
.spacing(20)
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.width(Length::Fill),
|
||||
)
|
||||
.push(separation().width(Length::Fill))
|
||||
@ -246,16 +246,16 @@ pub fn remote_backend_section<'a>(
|
||||
.push(
|
||||
Row::new()
|
||||
.spacing(10)
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.push(
|
||||
Button::new(text("Settings").size(30).bold())
|
||||
.style(theme::Button::Transparent)
|
||||
.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)
|
||||
.style(theme::button::transparent)
|
||||
.on_press(Message::Settings(
|
||||
SettingsMessage::EditRemoteBackendSettings,
|
||||
)),
|
||||
@ -279,7 +279,7 @@ pub fn remote_backend_section<'a>(
|
||||
.push(
|
||||
Row::new()
|
||||
.push_maybe(if success {
|
||||
Some(text("Invitation was sent").style(color::GREEN))
|
||||
Some(text("Invitation was sent").color(color::GREEN))
|
||||
} else {
|
||||
None
|
||||
})
|
||||
@ -318,7 +318,7 @@ pub fn bitcoind_edit<'a>(
|
||||
Row::new()
|
||||
.push(
|
||||
Row::new()
|
||||
.push(badge::Badge::new(icon::network_icon()))
|
||||
.push(badge::badge(icon::network_icon()))
|
||||
.push(
|
||||
Column::new()
|
||||
.push(text("Network:"))
|
||||
@ -329,7 +329,7 @@ pub fn bitcoind_edit<'a>(
|
||||
)
|
||||
.push(
|
||||
Row::new()
|
||||
.push(badge::Badge::new(icon::block_icon()))
|
||||
.push(badge::badge(icon::block_icon()))
|
||||
.push(
|
||||
Column::new()
|
||||
.push(text("Block Height:"))
|
||||
@ -358,7 +358,7 @@ pub fn bitcoind_edit<'a>(
|
||||
SettingsEditMessage::BitcoindRpcAuthTypeSelected,
|
||||
))
|
||||
.spacing(30)
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
},
|
||||
),
|
||||
)
|
||||
@ -423,11 +423,11 @@ pub fn bitcoind_edit<'a>(
|
||||
Column::new()
|
||||
.push(
|
||||
Row::new()
|
||||
.push(badge::Badge::new(icon::bitcoin_icon()))
|
||||
.push(badge::badge(icon::bitcoin_icon()))
|
||||
.push(text("Bitcoin Core").bold())
|
||||
.padding(10)
|
||||
.spacing(20)
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.width(Length::Fill),
|
||||
)
|
||||
.push(separation().width(Length::Fill))
|
||||
@ -438,7 +438,7 @@ pub fn bitcoind_edit<'a>(
|
||||
.push(cancel_button)
|
||||
.push(confirm_button)
|
||||
.spacing(10)
|
||||
.align_items(Alignment::Center),
|
||||
.align_y(Alignment::Center),
|
||||
)
|
||||
.width(Length::Fill)
|
||||
.align_x(alignment::Horizontal::Right),
|
||||
@ -464,7 +464,7 @@ pub fn bitcoind<'a>(
|
||||
Row::new()
|
||||
.push(
|
||||
Row::new()
|
||||
.push(badge::Badge::new(icon::network_icon()))
|
||||
.push(badge::badge(icon::network_icon()))
|
||||
.push(
|
||||
Column::new()
|
||||
.push(text("Network:"))
|
||||
@ -475,7 +475,7 @@ pub fn bitcoind<'a>(
|
||||
)
|
||||
.push(
|
||||
Row::new()
|
||||
.push(badge::Badge::new(icon::block_icon()))
|
||||
.push(badge::badge(icon::block_icon()))
|
||||
.push(
|
||||
Column::new()
|
||||
.push(text("Block Height:"))
|
||||
@ -516,10 +516,10 @@ pub fn bitcoind<'a>(
|
||||
.push(Space::with_width(10))
|
||||
.push(
|
||||
Button::new(icon::clipboard_icon())
|
||||
.style(theme::Button::TransparentBorder)
|
||||
.style(theme::button::transparent_border)
|
||||
.on_press(SettingsEditMessage::Clipboard(v.to_string())),
|
||||
)
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
});
|
||||
}
|
||||
|
||||
@ -529,7 +529,7 @@ pub fn bitcoind<'a>(
|
||||
Row::new()
|
||||
.push(
|
||||
Row::new()
|
||||
.push(badge::Badge::new(icon::bitcoin_icon()))
|
||||
.push(badge::badge(icon::bitcoin_icon()))
|
||||
.push(text("Bitcoin Core").bold())
|
||||
.push_maybe(if is_configured_node_type {
|
||||
Some(is_running_label(is_running))
|
||||
@ -537,17 +537,17 @@ pub fn bitcoind<'a>(
|
||||
None
|
||||
})
|
||||
.spacing(20)
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.width(Length::Fill),
|
||||
)
|
||||
.push(if can_edit {
|
||||
Button::new(icon::pencil_icon())
|
||||
.style(theme::Button::TransparentBorder)
|
||||
.style(theme::button::transparent_border)
|
||||
.on_press(SettingsEditMessage::Select)
|
||||
} else {
|
||||
Button::new(icon::pencil_icon()).style(theme::Button::TransparentBorder)
|
||||
Button::new(icon::pencil_icon()).style(theme::button::transparent_border)
|
||||
})
|
||||
.align_items(Alignment::Center),
|
||||
.align_y(Alignment::Center),
|
||||
)
|
||||
.push(separation().width(Length::Fill))
|
||||
.push(col.push(col_fields))
|
||||
@ -571,7 +571,7 @@ pub fn electrum_edit<'a>(
|
||||
Row::new()
|
||||
.push(
|
||||
Row::new()
|
||||
.push(badge::Badge::new(icon::network_icon()))
|
||||
.push(badge::badge(icon::network_icon()))
|
||||
.push(
|
||||
Column::new()
|
||||
.push(text("Network:"))
|
||||
@ -582,7 +582,7 @@ pub fn electrum_edit<'a>(
|
||||
)
|
||||
.push(
|
||||
Row::new()
|
||||
.push(badge::Badge::new(icon::block_icon()))
|
||||
.push(badge::badge(icon::block_icon()))
|
||||
.push(
|
||||
Column::new()
|
||||
.push(text("Block Height:"))
|
||||
@ -621,11 +621,11 @@ pub fn electrum_edit<'a>(
|
||||
Column::new()
|
||||
.push(
|
||||
Row::new()
|
||||
.push(badge::Badge::new(icon::bitcoin_icon()))
|
||||
.push(badge::badge(icon::bitcoin_icon()))
|
||||
.push(text("Electrum").bold())
|
||||
.padding(10)
|
||||
.spacing(20)
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.width(Length::Fill),
|
||||
)
|
||||
.push(separation().width(Length::Fill))
|
||||
@ -636,7 +636,7 @@ pub fn electrum_edit<'a>(
|
||||
.push(cancel_button)
|
||||
.push(confirm_button)
|
||||
.spacing(10)
|
||||
.align_items(Alignment::Center),
|
||||
.align_y(Alignment::Center),
|
||||
)
|
||||
.width(Length::Fill)
|
||||
.align_x(alignment::Horizontal::Right),
|
||||
@ -662,7 +662,7 @@ pub fn electrum<'a>(
|
||||
Row::new()
|
||||
.push(
|
||||
Row::new()
|
||||
.push(badge::Badge::new(icon::network_icon()))
|
||||
.push(badge::badge(icon::network_icon()))
|
||||
.push(
|
||||
Column::new()
|
||||
.push(text("Network:"))
|
||||
@ -673,7 +673,7 @@ pub fn electrum<'a>(
|
||||
)
|
||||
.push(
|
||||
Row::new()
|
||||
.push(badge::Badge::new(icon::block_icon()))
|
||||
.push(badge::badge(icon::block_icon()))
|
||||
.push(
|
||||
Column::new()
|
||||
.push(text("Block Height:"))
|
||||
@ -701,10 +701,10 @@ pub fn electrum<'a>(
|
||||
.push(Space::with_width(10))
|
||||
.push(
|
||||
Button::new(icon::clipboard_icon())
|
||||
.style(theme::Button::TransparentBorder)
|
||||
.style(theme::button::transparent_border)
|
||||
.on_press(SettingsEditMessage::Clipboard(v.to_string())),
|
||||
)
|
||||
.align_items(Alignment::Center),
|
||||
.align_y(Alignment::Center),
|
||||
);
|
||||
}
|
||||
|
||||
@ -714,7 +714,7 @@ pub fn electrum<'a>(
|
||||
Row::new()
|
||||
.push(
|
||||
Row::new()
|
||||
.push(badge::Badge::new(icon::bitcoin_icon()))
|
||||
.push(badge::badge(icon::bitcoin_icon()))
|
||||
.push(text("Electrum").bold())
|
||||
.push_maybe(if is_configured_node_type {
|
||||
Some(is_running_label(is_running))
|
||||
@ -722,17 +722,17 @@ pub fn electrum<'a>(
|
||||
None
|
||||
})
|
||||
.spacing(20)
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.width(Length::Fill),
|
||||
)
|
||||
.push(if can_edit {
|
||||
Button::new(icon::pencil_icon())
|
||||
.style(theme::Button::TransparentBorder)
|
||||
.style(theme::button::transparent_border)
|
||||
.on_press(SettingsEditMessage::Select)
|
||||
} else {
|
||||
Button::new(icon::pencil_icon()).style(theme::Button::TransparentBorder)
|
||||
Button::new(icon::pencil_icon()).style(theme::button::transparent_border)
|
||||
})
|
||||
.align_items(Alignment::Center),
|
||||
.align_y(Alignment::Center),
|
||||
)
|
||||
.push(separation().width(Length::Fill))
|
||||
.push(col.push(col_fields))
|
||||
@ -747,16 +747,16 @@ pub fn is_running_label<'a, T: 'a>(is_running: Option<bool>) -> Container<'a, T>
|
||||
if running {
|
||||
Container::new(
|
||||
Row::new()
|
||||
.push(icon::dot_icon().size(5).style(color::GREEN))
|
||||
.push(text("Running").small().style(color::GREEN))
|
||||
.align_items(Alignment::Center),
|
||||
.push(icon::dot_icon().size(5).color(color::GREEN))
|
||||
.push(text("Running").small().color(color::GREEN))
|
||||
.align_y(Alignment::Center),
|
||||
)
|
||||
} else {
|
||||
Container::new(
|
||||
Row::new()
|
||||
.push(icon::dot_icon().size(5).style(color::RED))
|
||||
.push(text("Not running").small().style(color::RED))
|
||||
.align_items(Alignment::Center),
|
||||
.push(icon::dot_icon().size(5).color(color::RED))
|
||||
.push(text("Not running").small().color(color::RED))
|
||||
.align_y(Alignment::Center),
|
||||
)
|
||||
}
|
||||
} else {
|
||||
@ -781,15 +781,15 @@ pub fn rescan<'a>(
|
||||
Column::new()
|
||||
.push(
|
||||
Row::new()
|
||||
.push(badge::Badge::new(icon::block_icon()))
|
||||
.push(badge::badge(icon::block_icon()))
|
||||
.push(text("Blockchain rescan").bold().width(Length::Fill))
|
||||
.push_maybe(if success {
|
||||
Some(text("Successfully rescanned the blockchain").style(color::GREEN))
|
||||
Some(text("Successfully rescanned the blockchain").color(color::GREEN))
|
||||
} else {
|
||||
None
|
||||
})
|
||||
.spacing(20)
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.width(Length::Fill),
|
||||
)
|
||||
.push(separation().width(Length::Fill))
|
||||
@ -830,24 +830,24 @@ pub fn rescan<'a>(
|
||||
.size(P1_SIZE)
|
||||
.padding(5),
|
||||
)
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.spacing(10),
|
||||
)
|
||||
.push_maybe(if invalid_date {
|
||||
Some(p1_regular("Provided date is invalid").style(color::RED))
|
||||
Some(p1_regular("Provided date is invalid").color(color::RED))
|
||||
} else {
|
||||
None
|
||||
})
|
||||
.push_maybe(if past_possible_height {
|
||||
Some(
|
||||
p1_regular("Provided date earlier than the node prune height")
|
||||
.style(color::RED),
|
||||
.color(color::RED),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
})
|
||||
.push_maybe(if future_date {
|
||||
Some(p1_regular("Provided date is in the future").style(color::RED))
|
||||
Some(p1_regular("Provided date is in the future").color(color::RED))
|
||||
} else {
|
||||
None
|
||||
})
|
||||
@ -910,16 +910,16 @@ pub fn wallet_settings<'a>(
|
||||
.push(
|
||||
Row::new()
|
||||
.spacing(10)
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.push(
|
||||
Button::new(text("Settings").size(30).bold())
|
||||
.style(theme::Button::Transparent)
|
||||
.style(theme::button::transparent)
|
||||
.on_press(Message::Menu(Menu::Settings)),
|
||||
)
|
||||
.push(icon::chevron_right().size(30))
|
||||
.push(
|
||||
Button::new(text("Wallet").size(30).bold())
|
||||
.style(theme::Button::Transparent)
|
||||
.style(theme::button::transparent)
|
||||
.on_press(Message::Settings(SettingsMessage::EditWalletSettings)),
|
||||
),
|
||||
)
|
||||
@ -935,7 +935,7 @@ pub fn wallet_settings<'a>(
|
||||
)
|
||||
.direction(
|
||||
scrollable::Direction::Horizontal(
|
||||
scrollable::Properties::new().width(5).scroller_width(5),
|
||||
scrollable::Scrollbar::new().width(5).scroller_width(5),
|
||||
),
|
||||
),
|
||||
)
|
||||
@ -973,7 +973,7 @@ pub fn wallet_settings<'a>(
|
||||
col.push(
|
||||
Row::new()
|
||||
.spacing(10)
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.push(
|
||||
text(fg.to_string()).bold().width(Length::Fixed(100.0)),
|
||||
)
|
||||
@ -994,14 +994,14 @@ pub fn wallet_settings<'a>(
|
||||
))
|
||||
.push(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.push(Space::with_width(Length::Fill))
|
||||
.push_maybe(if updated {
|
||||
Some(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.push(icon::circle_check_icon().style(color::GREEN))
|
||||
.push(text("Updated").style(color::GREEN)),
|
||||
.align_y(Alignment::Center)
|
||||
.push(icon::circle_check_icon().color(color::GREEN))
|
||||
.push(text("Updated").color(color::GREEN)),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
@ -1063,7 +1063,7 @@ fn display_policy(
|
||||
text(k.to_string()),
|
||||
iced_tooltip::Position::Bottom,
|
||||
)
|
||||
.style(theme::Container::Card(theme::Card::Simple)),
|
||||
.style(theme::card::simple),
|
||||
)
|
||||
} else {
|
||||
Container::new(text(format!("[{}]", k)).bold())
|
||||
@ -1116,7 +1116,7 @@ fn display_policy(
|
||||
text(k.to_string()),
|
||||
iced_tooltip::Position::Bottom,
|
||||
)
|
||||
.style(theme::Container::Card(theme::Card::Simple)),
|
||||
.style(theme::card::simple),
|
||||
)
|
||||
} else {
|
||||
Container::new(text(format!("[{}]", k)).bold())
|
||||
@ -1146,7 +1146,7 @@ fn display_policy(
|
||||
.spacing(10)
|
||||
.push(text("The wallet policy:").bold())
|
||||
.push(scrollable(col).direction(scrollable::Direction::Horizontal(
|
||||
scrollable::Properties::new().width(5).scroller_width(5),
|
||||
scrollable::Scrollbar::new().width(5).scroller_width(5),
|
||||
)))
|
||||
.into()
|
||||
}
|
||||
@ -1228,7 +1228,7 @@ pub fn register_wallet_modal<'a>(
|
||||
)
|
||||
.spacing(20)
|
||||
.width(Length::Fill)
|
||||
.align_items(Alignment::Center),
|
||||
.align_x(Alignment::Center),
|
||||
))
|
||||
.width(Length::Fixed(500.0))
|
||||
.into()
|
||||
|
||||
@ -57,8 +57,8 @@ pub fn spend_view<'a>(
|
||||
col.push(
|
||||
Row::new()
|
||||
.spacing(5)
|
||||
.push(icon::warning_icon().style(color::ORANGE))
|
||||
.push(text(warning).style(color::ORANGE)),
|
||||
.push(icon::warning_icon().color(color::ORANGE))
|
||||
.push(text(warning).color(color::ORANGE)),
|
||||
)
|
||||
},
|
||||
))
|
||||
@ -154,7 +154,7 @@ pub fn create_spend_tx<'a>(
|
||||
Some(
|
||||
Container::new(
|
||||
text("Two payment addresses are the same")
|
||||
.style(color::RED),
|
||||
.color(color::RED),
|
||||
)
|
||||
.padding(10),
|
||||
)
|
||||
@ -206,7 +206,7 @@ pub fn create_spend_tx<'a>(
|
||||
.spacing(10)
|
||||
.push(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.push(p1_bold("Coins selection").width(Length::Fill))
|
||||
.push(if is_self_send {
|
||||
Row::new()
|
||||
@ -226,7 +226,7 @@ pub fn create_spend_tx<'a>(
|
||||
),
|
||||
P2_SIZE,
|
||||
))
|
||||
.push(p2_regular("selected").style(color::GREY_3))
|
||||
.push(p2_regular("selected").color(color::GREY_3))
|
||||
} else if let Some(amount_left) = amount_left {
|
||||
if amount_left.to_sat() == 0 && !is_valid {
|
||||
// If amount left is set, the current configuration must be redraftable.
|
||||
@ -237,20 +237,20 @@ pub fn create_spend_tx<'a>(
|
||||
// and it has the max selected.
|
||||
Row::new().push(
|
||||
text("Select at least one coin.")
|
||||
.style(color::GREY_3),
|
||||
.color(color::GREY_3),
|
||||
)
|
||||
} else {
|
||||
// There must be a recipient with max selected and value 0.
|
||||
Row::new().push(
|
||||
text("Check max amount for recipient.")
|
||||
.style(color::GREY_3),
|
||||
.color(color::GREY_3),
|
||||
)
|
||||
}
|
||||
} else {
|
||||
Row::new()
|
||||
.spacing(5)
|
||||
.push(amount_with_size(amount_left, P2_SIZE))
|
||||
.push(p2_regular("left to select").style(color::GREY_3))
|
||||
.push(p2_regular("left to select").color(color::GREY_3))
|
||||
}
|
||||
} else {
|
||||
Row::new().push(
|
||||
@ -259,7 +259,7 @@ pub fn create_spend_tx<'a>(
|
||||
} else {
|
||||
"Add recipient details."
|
||||
})
|
||||
.style(color::GREY_3),
|
||||
.color(color::GREY_3),
|
||||
)
|
||||
})
|
||||
.width(Length::Fill),
|
||||
@ -282,12 +282,12 @@ pub fn create_spend_tx<'a>(
|
||||
),
|
||||
)
|
||||
.padding(20)
|
||||
.style(theme::Card::Simple),
|
||||
.style(theme::card::simple),
|
||||
)
|
||||
.push(
|
||||
Row::new()
|
||||
.spacing(20)
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.push(Space::with_width(Length::Fill))
|
||||
.push(
|
||||
button::secondary(None, "Clear")
|
||||
@ -325,14 +325,14 @@ pub fn recipient_view<'a>(
|
||||
.push(
|
||||
Row::new().push(Space::with_width(Length::Fill)).push(
|
||||
Button::new(icon::cross_icon())
|
||||
.style(theme::Button::Transparent)
|
||||
.style(theme::button::transparent)
|
||||
.on_press(CreateSpendMessage::DeleteRecipient(index))
|
||||
.width(Length::Shrink),
|
||||
),
|
||||
)
|
||||
.push(
|
||||
Row::new()
|
||||
.align_items(Alignment::Start)
|
||||
.align_y(Alignment::Start)
|
||||
.spacing(10)
|
||||
.push(
|
||||
Container::new(p1_bold("Address"))
|
||||
@ -351,7 +351,7 @@ pub fn recipient_view<'a>(
|
||||
)
|
||||
.push(
|
||||
Row::new()
|
||||
.align_items(Alignment::Start)
|
||||
.align_y(Alignment::Start)
|
||||
.spacing(10)
|
||||
.push(
|
||||
Container::new(p1_bold("Description"))
|
||||
@ -370,7 +370,7 @@ pub fn recipient_view<'a>(
|
||||
)
|
||||
.push(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.spacing(10)
|
||||
.push(
|
||||
Container::new(p1_bold("Amount"))
|
||||
@ -384,7 +384,7 @@ pub fn recipient_view<'a>(
|
||||
.map(amount_as_string)
|
||||
.unwrap_or(amount.value.clone());
|
||||
Some(
|
||||
Container::new(text(amount_txt).size(P1_SIZE).style(color::GREY_2))
|
||||
Container::new(text(amount_txt).size(P1_SIZE).color(color::GREY_2))
|
||||
.padding(10)
|
||||
.width(Length::Fill),
|
||||
)
|
||||
@ -414,7 +414,7 @@ pub fn recipient_view<'a>(
|
||||
),
|
||||
)
|
||||
.padding(20)
|
||||
.style(theme::Card::Simple)
|
||||
.style(theme::card::simple)
|
||||
.into()
|
||||
}
|
||||
|
||||
@ -445,7 +445,7 @@ fn coin_list_view<'a>(
|
||||
// It is not possible to know if a coin is a
|
||||
// change coin or not so for now, From is
|
||||
// enough
|
||||
p1_regular("From").style(color::GREY_3),
|
||||
p1_regular("From").color(color::GREY_3),
|
||||
)
|
||||
.push(p1_regular(label)),
|
||||
)
|
||||
@ -463,13 +463,13 @@ fn coin_list_view<'a>(
|
||||
coins::coin_sequence_label(seq, timelock as u32)
|
||||
})
|
||||
.spacing(10)
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.width(Length::Fill),
|
||||
)
|
||||
.push(amount(&coin.amount))
|
||||
// give some space for the scroll bar without using padding
|
||||
.push(Space::with_width(Length::Fixed(0.0)))
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.spacing(20)
|
||||
.into()
|
||||
}
|
||||
|
||||
@ -67,11 +67,11 @@ pub fn transactions_view<'a>(
|
||||
"See more"
|
||||
})
|
||||
.width(Length::Fill)
|
||||
.horizontal_alignment(alignment::Horizontal::Center),
|
||||
.align_x(alignment::Horizontal::Center),
|
||||
)
|
||||
.width(Length::Fill)
|
||||
.padding(15)
|
||||
.style(theme::Button::TransparentBorder)
|
||||
.style(theme::button::transparent_border)
|
||||
.on_press_maybe(if !processing {
|
||||
Some(Message::Next)
|
||||
} else {
|
||||
@ -79,13 +79,13 @@ pub fn transactions_view<'a>(
|
||||
}),
|
||||
)
|
||||
.width(Length::Fill)
|
||||
.style(theme::Container::Card(theme::Card::Simple)),
|
||||
.style(theme::card::simple),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
}),
|
||||
)
|
||||
.align_items(Alignment::Center)
|
||||
.align_x(Alignment::Center)
|
||||
.spacing(30),
|
||||
)
|
||||
}
|
||||
@ -121,13 +121,13 @@ fn tx_list_view(i: usize, tx: &HistoryTransaction) -> Element<'_, Message> {
|
||||
.format("%b. %d, %Y - %T")
|
||||
.to_string(),
|
||||
)
|
||||
.style(color::GREY_3)
|
||||
.color(color::GREY_3)
|
||||
.small(),
|
||||
)
|
||||
})),
|
||||
)
|
||||
.spacing(10)
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.width(Length::Fill),
|
||||
)
|
||||
.push_maybe(if tx.time.is_none() {
|
||||
@ -145,24 +145,24 @@ fn tx_list_view(i: usize, tx: &HistoryTransaction) -> Element<'_, Message> {
|
||||
.spacing(5)
|
||||
.push(text("+"))
|
||||
.push(amount(&tx.incoming_amount))
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
} else if tx.outgoing_amount != Amount::from_sat(0) {
|
||||
Row::new()
|
||||
.spacing(5)
|
||||
.push(text("-"))
|
||||
.push(amount(&tx.outgoing_amount))
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
} else {
|
||||
Row::new().push(text("Self-transfer"))
|
||||
})
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.spacing(20),
|
||||
)
|
||||
.padding(10)
|
||||
.on_press(Message::Select(i))
|
||||
.style(theme::Button::TransparentBorder),
|
||||
.style(theme::button::transparent_border),
|
||||
)
|
||||
.style(theme::Container::Card(theme::Card::Simple))
|
||||
.style(theme::card::simple)
|
||||
.into()
|
||||
}
|
||||
|
||||
@ -235,12 +235,12 @@ pub fn create_rbf_modal<'a>(
|
||||
Row::new()
|
||||
.padding([0, 30])
|
||||
.spacing(5)
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.push(text(txid.to_string()))
|
||||
.push(
|
||||
Button::new(icon::clipboard_icon().style(color::GREY_3))
|
||||
Button::new(icon::clipboard_icon().color(color::GREY_3))
|
||||
.on_press(Message::Clipboard(txid.to_string()))
|
||||
.style(theme::Button::TransparentBorder),
|
||||
.style(theme::button::transparent_border),
|
||||
),
|
||||
)
|
||||
},
|
||||
@ -274,11 +274,11 @@ pub fn create_rbf_modal<'a>(
|
||||
} else {
|
||||
Row::new()
|
||||
.spacing(10)
|
||||
.align_items(Alignment::Center)
|
||||
.push(icon::circle_check_icon().style(color::GREEN))
|
||||
.align_y(Alignment::Center)
|
||||
.push(icon::circle_check_icon().color(color::GREEN))
|
||||
.push(
|
||||
text("Replacement PSBT created successfully and ready to be signed")
|
||||
.style(color::GREEN),
|
||||
.color(color::GREEN),
|
||||
)
|
||||
}))
|
||||
.push_maybe(replacement_txid.map(|id| {
|
||||
@ -342,8 +342,8 @@ pub fn tx_view<'a>(
|
||||
})
|
||||
.push_maybe(tx.fee_amount.map(|fee_amount| {
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.push(h3("Miner fee: ").style(color::GREY_3))
|
||||
.align_y(Alignment::Center)
|
||||
.push(h3("Miner fee: ").color(color::GREY_3))
|
||||
.push(amount_with_size(&fee_amount, H3_SIZE))
|
||||
.push(text(" ").size(H3_SIZE))
|
||||
.push(
|
||||
@ -352,7 +352,7 @@ pub fn tx_view<'a>(
|
||||
fee_amount.to_sat() / tx.tx.vsize() as u64
|
||||
))
|
||||
.size(H4_SIZE)
|
||||
.style(color::GREY_3),
|
||||
.color(color::GREY_3),
|
||||
)
|
||||
})),
|
||||
),
|
||||
@ -396,16 +396,16 @@ pub fn tx_view<'a>(
|
||||
.push(
|
||||
Row::new()
|
||||
.width(Length::Fill)
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.push(Container::new(text("Txid:").bold()).width(Length::Fill))
|
||||
.push(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.push(Container::new(text(txid.clone()).small()))
|
||||
.push(
|
||||
Button::new(icon::clipboard_icon())
|
||||
.on_press(Message::Clipboard(txid.clone()))
|
||||
.style(theme::Button::TransparentBorder),
|
||||
.style(theme::button::transparent_border),
|
||||
)
|
||||
.width(Length::Shrink),
|
||||
),
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
use iced::Command;
|
||||
use iced::Task;
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
path::PathBuf,
|
||||
@ -215,7 +215,7 @@ impl HardwareWallets {
|
||||
pub fn update(
|
||||
&mut self,
|
||||
message: HardwareWalletMessage,
|
||||
) -> Result<Command<HardwareWalletMessage>, async_hwi::Error> {
|
||||
) -> Result<Task<HardwareWalletMessage>, async_hwi::Error> {
|
||||
match message {
|
||||
HardwareWalletMessage::Error(e) => Err(async_hwi::Error::Device(e)),
|
||||
HardwareWalletMessage::List(ConnectedList { still, mut new }) => {
|
||||
@ -237,7 +237,7 @@ impl HardwareWallets {
|
||||
let id = id.to_string();
|
||||
let network = self.network;
|
||||
let wallet = self.wallet.clone();
|
||||
cmds.push(Command::perform(
|
||||
cmds.push(Task::perform(
|
||||
async move {
|
||||
(
|
||||
id.clone(),
|
||||
@ -252,7 +252,7 @@ impl HardwareWallets {
|
||||
let id_cloned = id.clone();
|
||||
let network = self.network;
|
||||
let wallet = self.wallet.clone();
|
||||
cmds.push(Command::perform(
|
||||
cmds.push(Task::perform(
|
||||
async move {
|
||||
if let Err(e) = device.auth().await {
|
||||
return (id_cloned, Err(e.into()));
|
||||
@ -278,9 +278,9 @@ impl HardwareWallets {
|
||||
}
|
||||
}
|
||||
if cmds.is_empty() {
|
||||
Ok(Command::none())
|
||||
Ok(Task::none())
|
||||
} else {
|
||||
Ok(Command::batch(cmds))
|
||||
Ok(Task::batch(cmds))
|
||||
}
|
||||
}
|
||||
HardwareWalletMessage::Unlocked(id, res) => {
|
||||
@ -307,7 +307,7 @@ impl HardwareWallets {
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(Command::none())
|
||||
Ok(Task::none())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,7 +4,7 @@ mod prompt;
|
||||
mod step;
|
||||
mod view;
|
||||
|
||||
use iced::{clipboard, Command, Subscription};
|
||||
use iced::{clipboard, Subscription, Task};
|
||||
use liana::miniscript::bitcoin::{self, Network};
|
||||
use liana_ui::{
|
||||
component::network_banner,
|
||||
@ -64,13 +64,13 @@ pub struct Installer {
|
||||
}
|
||||
|
||||
impl Installer {
|
||||
fn previous(&mut self) -> Command<Message> {
|
||||
fn previous(&mut self) -> Task<Message> {
|
||||
self.hws.reset_watch_list();
|
||||
let network = self.network;
|
||||
if self.current > 0 {
|
||||
self.current -= 1;
|
||||
} else {
|
||||
return Command::perform(async move { network }, Message::BackToLauncher);
|
||||
return Task::perform(async move { network }, Message::BackToLauncher);
|
||||
}
|
||||
// skip the previous step according to the current context.
|
||||
while self
|
||||
@ -82,14 +82,14 @@ impl Installer {
|
||||
if self.current > 0 {
|
||||
self.current -= 1;
|
||||
} else {
|
||||
return Command::perform(async move { network }, Message::BackToLauncher);
|
||||
return Task::perform(async move { network }, Message::BackToLauncher);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(step) = self.steps.get(self.current) {
|
||||
step.revert(&mut self.context)
|
||||
}
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
|
||||
pub fn new(
|
||||
@ -97,7 +97,7 @@ impl Installer {
|
||||
network: bitcoin::Network,
|
||||
remote_backend: Option<BackendClient>,
|
||||
user_flow: UserFlow,
|
||||
) -> (Installer, Command<Message>) {
|
||||
) -> (Installer, Task<Message>) {
|
||||
let signer = Arc::new(Mutex::new(Signer::generate(network).unwrap()));
|
||||
let context = Context::new(
|
||||
network,
|
||||
@ -197,7 +197,7 @@ impl Installer {
|
||||
}
|
||||
}
|
||||
|
||||
fn next(&mut self) -> Command<Message> {
|
||||
fn next(&mut self) -> Task<Message> {
|
||||
self.hws.reset_watch_list();
|
||||
let current_step = self
|
||||
.steps
|
||||
@ -209,7 +209,7 @@ impl Installer {
|
||||
} else {
|
||||
// The step is already the last current step.
|
||||
// No need to reload the current step.
|
||||
return Command::none();
|
||||
return Task::none();
|
||||
}
|
||||
// skip the step according to the current context.
|
||||
self.skip_steps();
|
||||
@ -222,16 +222,16 @@ impl Installer {
|
||||
current_step.load_context(&self.context);
|
||||
return current_step.load();
|
||||
}
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
|
||||
pub fn update(&mut self, message: Message) -> Command<Message> {
|
||||
pub fn update(&mut self, message: Message) -> Task<Message> {
|
||||
match message {
|
||||
Message::HardwareWallets(msg) => match self.hws.update(msg) {
|
||||
Ok(cmd) => cmd.map(Message::HardwareWallets),
|
||||
Err(e) => {
|
||||
error!("{}", e);
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
},
|
||||
Message::Clibpboard(s) => clipboard::write(s),
|
||||
@ -244,7 +244,7 @@ impl Installer {
|
||||
.expect("There is always a step")
|
||||
.update(&mut self.hws, message);
|
||||
match &self.context.remote_backend {
|
||||
RemoteBackend::WithoutWallet(backend) => Command::perform(
|
||||
RemoteBackend::WithoutWallet(backend) => Task::perform(
|
||||
create_remote_wallet(
|
||||
self.context.clone(),
|
||||
self.signer.clone(),
|
||||
@ -252,11 +252,11 @@ impl Installer {
|
||||
),
|
||||
Message::Installed,
|
||||
),
|
||||
RemoteBackend::WithWallet(backend) => Command::perform(
|
||||
RemoteBackend::WithWallet(backend) => Task::perform(
|
||||
import_remote_wallet(self.context.clone(), backend.clone()),
|
||||
Message::Installed,
|
||||
),
|
||||
RemoteBackend::None => Command::perform(
|
||||
RemoteBackend::None => Task::perform(
|
||||
install_local_wallet(self.context.clone(), self.signer.clone()),
|
||||
Message::Installed,
|
||||
),
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
use std::str::FromStr;
|
||||
|
||||
use iced::Command;
|
||||
use iced::Task;
|
||||
|
||||
use liana::{descriptors::LianaDescriptor, miniscript::bitcoin::Network};
|
||||
use liana_ui::{component::form, widget::Element};
|
||||
@ -44,15 +44,15 @@ impl Step for ChooseBackend {
|
||||
fn skip(&self, _ctx: &Context) -> bool {
|
||||
self.network != Network::Bitcoin && self.network != Network::Signet
|
||||
}
|
||||
fn update(&mut self, _hws: &mut HardwareWallets, message: Message) -> Command<Message> {
|
||||
fn update(&mut self, _hws: &mut HardwareWallets, message: Message) -> Task<Message> {
|
||||
if let Message::SelectBackend(message::SelectBackend::ContinueWithLocalWallet(
|
||||
local_wallet,
|
||||
)) = message
|
||||
{
|
||||
self.remote_backend_is_selected = !local_wallet;
|
||||
Command::perform(async move {}, |_| Message::Next)
|
||||
Task::perform(async move {}, |_| Message::Next)
|
||||
} else {
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
}
|
||||
|
||||
@ -128,7 +128,7 @@ impl Step for RemoteBackendLogin {
|
||||
matches!(ctx.remote_backend, RemoteBackend::None)
|
||||
|| (self.network != Network::Bitcoin && self.network != Network::Signet)
|
||||
}
|
||||
fn update(&mut self, _hws: &mut HardwareWallets, message: Message) -> Command<Message> {
|
||||
fn update(&mut self, _hws: &mut HardwareWallets, message: Message) -> Task<Message> {
|
||||
match &mut self.step {
|
||||
ConnectionStep::EnterEmail { email } => match message {
|
||||
Message::SelectBackend(message::SelectBackend::EmailEdited(value)) => {
|
||||
@ -149,7 +149,7 @@ impl Step for RemoteBackendLogin {
|
||||
self.processing = true;
|
||||
self.connection_error = None;
|
||||
self.auth_error = None;
|
||||
return Command::perform(
|
||||
return Task::perform(
|
||||
async move {
|
||||
let config =
|
||||
client::get_service_config(network).await.map_err(|e| {
|
||||
@ -211,7 +211,7 @@ impl Step for RemoteBackendLogin {
|
||||
self.processing = true;
|
||||
self.connection_error = None;
|
||||
self.auth_error = None;
|
||||
return Command::perform(
|
||||
return Task::perform(
|
||||
async move {
|
||||
client.resend_otp().await?;
|
||||
Ok(())
|
||||
@ -236,7 +236,7 @@ impl Step for RemoteBackendLogin {
|
||||
self.connection_error = None;
|
||||
self.auth_error = None;
|
||||
let network = self.network;
|
||||
return Command::perform(
|
||||
return Task::perform(
|
||||
async move { connect(client, otp, backend_api_url, network).await },
|
||||
message::SelectBackend::Connected,
|
||||
)
|
||||
@ -252,7 +252,7 @@ impl Step for RemoteBackendLogin {
|
||||
email: email.clone(),
|
||||
remote_backend,
|
||||
};
|
||||
return Command::perform(async move {}, |_| Message::Next);
|
||||
return Task::perform(async move {}, |_| Message::Next);
|
||||
}
|
||||
Err(e) => {
|
||||
if let Error::Auth(AuthError { http_status, .. }) = e {
|
||||
@ -278,7 +278,7 @@ impl Step for RemoteBackendLogin {
|
||||
}
|
||||
}
|
||||
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
|
||||
fn apply(&mut self, ctx: &mut Context) -> bool {
|
||||
@ -377,9 +377,9 @@ impl Step for ImportRemoteWallet {
|
||||
fn load_context(&mut self, ctx: &Context) {
|
||||
self.backend = ctx.remote_backend.clone();
|
||||
}
|
||||
fn load(&self) -> Command<Message> {
|
||||
fn load(&self) -> Task<Message> {
|
||||
let backend = self.backend.clone();
|
||||
Command::perform(
|
||||
Task::perform(
|
||||
async move {
|
||||
let wallets = match backend {
|
||||
context::RemoteBackend::WithoutWallet(backend) => {
|
||||
@ -398,7 +398,7 @@ impl Step for ImportRemoteWallet {
|
||||
}
|
||||
// form value is set as valid each time it is edited.
|
||||
// Verification of the values is happening when the user click on Next button.
|
||||
fn update(&mut self, _hws: &mut HardwareWallets, message: Message) -> Command<Message> {
|
||||
fn update(&mut self, _hws: &mut HardwareWallets, message: Message) -> Task<Message> {
|
||||
match message {
|
||||
Message::ImportRemoteWallet(message::ImportRemoteWallet::ImportDescriptor(desc)) => {
|
||||
self.imported_descriptor.value = desc;
|
||||
@ -430,7 +430,7 @@ impl Step for ImportRemoteWallet {
|
||||
context::RemoteBackend::WithoutWallet(backend.into_inner());
|
||||
}
|
||||
self.descriptor = Some(desc);
|
||||
return Command::perform(async {}, |_| Message::Next);
|
||||
return Task::perform(async {}, |_| Message::Next);
|
||||
}
|
||||
} else {
|
||||
self.imported_descriptor.valid = false;
|
||||
@ -455,7 +455,7 @@ impl Step for ImportRemoteWallet {
|
||||
};
|
||||
let token = self.invitation_token.value.clone();
|
||||
self.error = None;
|
||||
return Command::perform(
|
||||
return Task::perform(
|
||||
async move {
|
||||
let invitation = backend.get_wallet_invitation(&token).await?;
|
||||
Ok(invitation)
|
||||
@ -481,7 +481,7 @@ impl Step for ImportRemoteWallet {
|
||||
};
|
||||
let invitation = self.invitation.clone().expect("Invitation was fetched");
|
||||
self.error = None;
|
||||
return Command::perform(
|
||||
return Task::perform(
|
||||
async move {
|
||||
backend.accept_wallet_invitation(&invitation.id).await?;
|
||||
let wallets = backend.list_wallets().await?;
|
||||
@ -531,13 +531,13 @@ impl Step for ImportRemoteWallet {
|
||||
// ensure that no descriptor is imported.
|
||||
self.imported_descriptor = form::Value::default();
|
||||
self.descriptor = Some(wallet.descriptor);
|
||||
return Command::perform(async {}, |_| Message::Next);
|
||||
return Task::perform(async {}, |_| Message::Next);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
|
||||
fn apply(&mut self, ctx: &mut Context) -> bool {
|
||||
|
||||
@ -2,7 +2,7 @@ use std::collections::HashSet;
|
||||
use std::str::FromStr;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use iced::{Command, Subscription};
|
||||
use iced::{Subscription, Task};
|
||||
use liana::miniscript::bitcoin::bip32::Xpub;
|
||||
use liana::miniscript::{
|
||||
bitcoin::{
|
||||
@ -137,8 +137,8 @@ impl EditXpubModal {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn load(&self) -> Command<Message> {
|
||||
Command::none()
|
||||
pub fn load(&self) -> Task<Message> {
|
||||
Task::none()
|
||||
}
|
||||
}
|
||||
|
||||
@ -147,7 +147,7 @@ impl super::DescriptorEditModal for EditXpubModal {
|
||||
self.processing
|
||||
}
|
||||
|
||||
fn update(&mut self, hws: &mut HardwareWallets, message: Message) -> Command<Message> {
|
||||
fn update(&mut self, hws: &mut HardwareWallets, message: Message) -> Task<Message> {
|
||||
// Reset these fields.
|
||||
// the function will setup them again if something is wrong
|
||||
self.duplicate_master_fg = false;
|
||||
@ -167,10 +167,19 @@ impl super::DescriptorEditModal for EditXpubModal {
|
||||
let device_version = version.clone();
|
||||
let fingerprint = *fingerprint;
|
||||
let device_kind = *kind;
|
||||
let device_cloned = device.clone();
|
||||
let network = self.network;
|
||||
return Command::perform(
|
||||
get_extended_pubkey(device.clone(), fingerprint, self.network),
|
||||
move |res| {
|
||||
return Task::perform(
|
||||
async move {
|
||||
(
|
||||
device_version,
|
||||
device_kind,
|
||||
fingerprint,
|
||||
network,
|
||||
get_extended_pubkey(device_cloned, fingerprint, network).await,
|
||||
)
|
||||
},
|
||||
|(device_version, device_kind, fingerprint, network, res)| {
|
||||
Message::DefineDescriptor(message::DefineDescriptor::KeyModal(
|
||||
message::ImportKeyModal::FetchedKey(match res {
|
||||
Err(e) => Err(e),
|
||||
@ -306,7 +315,7 @@ impl super::DescriptorEditModal for EditXpubModal {
|
||||
self.duplicate_master_fg = true;
|
||||
} else {
|
||||
let coordinate = self.keys_coordinate.clone();
|
||||
return Command::perform(
|
||||
return Task::perform(
|
||||
async move { (coordinate, key) },
|
||||
move |(coordinate, key)| {
|
||||
message::DefineDescriptor::KeysEdited(coordinate, key)
|
||||
@ -326,7 +335,7 @@ impl super::DescriptorEditModal for EditXpubModal {
|
||||
},
|
||||
_ => {}
|
||||
};
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
|
||||
fn subscription(&self, hws: &HardwareWallets) -> Subscription<Message> {
|
||||
|
||||
@ -6,7 +6,7 @@ use std::iter::FromIterator;
|
||||
use std::str::FromStr;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use iced::{Command, Subscription};
|
||||
use iced::{Subscription, Task};
|
||||
use liana::{
|
||||
descriptors::{LianaDescriptor, LianaPolicy, PathInfo},
|
||||
miniscript::{
|
||||
@ -38,8 +38,8 @@ pub trait DescriptorEditModal {
|
||||
fn processing(&self) -> bool {
|
||||
false
|
||||
}
|
||||
fn update(&mut self, _hws: &mut HardwareWallets, _message: Message) -> Command<Message> {
|
||||
Command::none()
|
||||
fn update(&mut self, _hws: &mut HardwareWallets, _message: Message) -> Task<Message> {
|
||||
Task::none()
|
||||
}
|
||||
fn view<'a>(&'a self, _hws: &'a HardwareWallets) -> Element<'a, Message>;
|
||||
fn subscription(&self, _hws: &HardwareWallets) -> Subscription<Message> {
|
||||
@ -202,7 +202,7 @@ impl Step for DefineDescriptor {
|
||||
}
|
||||
// form value is set as valid each time it is edited.
|
||||
// Verification of the values is happening when the user click on Next button.
|
||||
fn update(&mut self, hws: &mut HardwareWallets, message: Message) -> Command<Message> {
|
||||
fn update(&mut self, hws: &mut HardwareWallets, message: Message) -> Task<Message> {
|
||||
self.error = None;
|
||||
match message {
|
||||
Message::Close => {
|
||||
@ -294,7 +294,7 @@ impl Step for DefineDescriptor {
|
||||
}
|
||||
message::DefinePath::Key(j, msg) => match msg {
|
||||
message::DefineKey::Clipboard(key) => {
|
||||
return Command::perform(async move { key }, Message::Clibpboard);
|
||||
return Task::perform(async move { key }, Message::Clibpboard);
|
||||
}
|
||||
|
||||
message::DefineKey::Edit => {
|
||||
@ -347,7 +347,7 @@ impl Step for DefineDescriptor {
|
||||
}
|
||||
}
|
||||
};
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
|
||||
fn subscription(&self, hws: &HardwareWallets) -> Subscription<Message> {
|
||||
@ -553,7 +553,7 @@ impl DescriptorEditModal for EditSequenceModal {
|
||||
false
|
||||
}
|
||||
|
||||
fn update(&mut self, _hws: &mut HardwareWallets, message: Message) -> Command<Message> {
|
||||
fn update(&mut self, _hws: &mut HardwareWallets, message: Message) -> Task<Message> {
|
||||
if let Message::DefineDescriptor(message::DefineDescriptor::ThresholdSequenceModal(msg)) =
|
||||
message
|
||||
{
|
||||
@ -570,7 +570,7 @@ impl DescriptorEditModal for EditSequenceModal {
|
||||
if self.sequence.valid {
|
||||
if let Ok(sequence) = u16::from_str(&self.sequence.value) {
|
||||
let path_index = self.path_index;
|
||||
return Command::perform(
|
||||
return Task::perform(
|
||||
async move { (path_index, sequence) },
|
||||
|(path_index, sequence)| {
|
||||
message::DefineDescriptor::Path(
|
||||
@ -586,7 +586,7 @@ impl DescriptorEditModal for EditSequenceModal {
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
|
||||
fn view(&self, _hws: &HardwareWallets) -> Element<Message> {
|
||||
@ -613,7 +613,7 @@ impl DescriptorEditModal for EditThresholdModal {
|
||||
false
|
||||
}
|
||||
|
||||
fn update(&mut self, _hws: &mut HardwareWallets, message: Message) -> Command<Message> {
|
||||
fn update(&mut self, _hws: &mut HardwareWallets, message: Message) -> Task<Message> {
|
||||
if let Message::DefineDescriptor(message::DefineDescriptor::ThresholdSequenceModal(msg)) =
|
||||
message
|
||||
{
|
||||
@ -626,7 +626,7 @@ impl DescriptorEditModal for EditThresholdModal {
|
||||
message::ThresholdSequenceModal::Confirm => {
|
||||
let path_index = self.path_index;
|
||||
let threshold = self.threshold.0;
|
||||
return Command::perform(
|
||||
return Task::perform(
|
||||
async move { (path_index, threshold) },
|
||||
|(path_index, threshold)| {
|
||||
message::DefineDescriptor::Path(
|
||||
@ -640,7 +640,7 @@ impl DescriptorEditModal for EditThresholdModal {
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
|
||||
fn view(&self, _hws: &HardwareWallets) -> Element<Message> {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
use iced::Command;
|
||||
use iced::Task;
|
||||
|
||||
use liana_ui::widget::Element;
|
||||
|
||||
@ -23,12 +23,12 @@ impl From<ChooseDescriptorTemplate> for Box<dyn Step> {
|
||||
}
|
||||
}
|
||||
impl Step for ChooseDescriptorTemplate {
|
||||
fn update(&mut self, _hws: &mut HardwareWallets, message: Message) -> Command<Message> {
|
||||
fn update(&mut self, _hws: &mut HardwareWallets, message: Message) -> Task<Message> {
|
||||
if let Message::SelectDescriptorTemplate(template) = message {
|
||||
self.template = template;
|
||||
Command::perform(async move {}, |_| Message::Next)
|
||||
Task::perform(async move {}, |_| Message::Next)
|
||||
} else {
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@ use std::{
|
||||
str::FromStr,
|
||||
};
|
||||
|
||||
use iced::{Command, Subscription};
|
||||
use iced::{Subscription, Task};
|
||||
use liana::{
|
||||
descriptors::LianaDescriptor,
|
||||
miniscript::bitcoin::{bip32::Fingerprint, Network},
|
||||
@ -77,14 +77,14 @@ impl Step for ImportDescriptor {
|
||||
}
|
||||
// form value is set as valid each time it is edited.
|
||||
// Verification of the values is happening when the user click on Next button.
|
||||
fn update(&mut self, _hws: &mut HardwareWallets, message: Message) -> Command<Message> {
|
||||
fn update(&mut self, _hws: &mut HardwareWallets, message: Message) -> Task<Message> {
|
||||
if let Message::DefineDescriptor(message::DefineDescriptor::ImportDescriptor(desc)) =
|
||||
message
|
||||
{
|
||||
self.imported_descriptor.value = desc;
|
||||
self.check_descriptor(self.network);
|
||||
}
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
|
||||
fn apply(&mut self, ctx: &mut Context) -> bool {
|
||||
@ -173,7 +173,7 @@ impl Step for RegisterDescriptor {
|
||||
map.insert(key.master_fingerprint, key.name.clone());
|
||||
}
|
||||
}
|
||||
fn update(&mut self, hws: &mut HardwareWallets, message: Message) -> Command<Message> {
|
||||
fn update(&mut self, hws: &mut HardwareWallets, message: Message) -> Task<Message> {
|
||||
match message {
|
||||
Message::Select(i) => {
|
||||
if let Some(HardwareWallet::Supported {
|
||||
@ -188,7 +188,7 @@ impl Step for RegisterDescriptor {
|
||||
self.chosen_hw = Some(i);
|
||||
self.processing = true;
|
||||
self.error = None;
|
||||
return Command::perform(
|
||||
return Task::perform(
|
||||
register_wallet(
|
||||
device.clone(),
|
||||
*fingerprint,
|
||||
@ -229,7 +229,7 @@ impl Step for RegisterDescriptor {
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
fn skip(&self, ctx: &Context) -> bool {
|
||||
!ctx.hw_is_used
|
||||
@ -243,8 +243,8 @@ impl Step for RegisterDescriptor {
|
||||
fn subscription(&self, hws: &HardwareWallets) -> Subscription<Message> {
|
||||
hws.refresh().map(Message::HardwareWallets)
|
||||
}
|
||||
fn load(&self) -> Command<Message> {
|
||||
Command::none()
|
||||
fn load(&self) -> Task<Message> {
|
||||
Task::none()
|
||||
}
|
||||
fn view<'a>(
|
||||
&'a self,
|
||||
@ -295,11 +295,11 @@ pub struct BackupDescriptor {
|
||||
}
|
||||
|
||||
impl Step for BackupDescriptor {
|
||||
fn update(&mut self, _hws: &mut HardwareWallets, message: Message) -> Command<Message> {
|
||||
fn update(&mut self, _hws: &mut HardwareWallets, message: Message) -> Task<Message> {
|
||||
if let Message::UserActionDone(done) = message {
|
||||
self.done = done;
|
||||
}
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
fn load_context(&mut self, ctx: &Context) {
|
||||
if self.descriptor != ctx.descriptor {
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use std::collections::HashSet;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use iced::Command;
|
||||
use iced::Task;
|
||||
use liana::{bip39, signer::HotSigner};
|
||||
|
||||
use liana_ui::widget::Element;
|
||||
@ -36,11 +36,11 @@ impl From<BackupMnemonic> for Box<dyn Step> {
|
||||
}
|
||||
|
||||
impl Step for BackupMnemonic {
|
||||
fn update(&mut self, _hws: &mut HardwareWallets, message: Message) -> Command<Message> {
|
||||
fn update(&mut self, _hws: &mut HardwareWallets, message: Message) -> Task<Message> {
|
||||
if let Message::UserActionDone(done) = message {
|
||||
self.done = done;
|
||||
}
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
fn skip(&self, ctx: &Context) -> bool {
|
||||
if let Some(descriptor) = &ctx.descriptor {
|
||||
@ -92,7 +92,7 @@ impl From<RecoverMnemonic> for Box<dyn Step> {
|
||||
}
|
||||
|
||||
impl Step for RecoverMnemonic {
|
||||
fn update(&mut self, _hws: &mut HardwareWallets, message: Message) -> Command<Message> {
|
||||
fn update(&mut self, _hws: &mut HardwareWallets, message: Message) -> Task<Message> {
|
||||
match message {
|
||||
Message::MnemonicWord(index, value) => {
|
||||
if let Some((word, valid)) = self.words.get_mut(index) {
|
||||
@ -116,11 +116,11 @@ impl Step for RecoverMnemonic {
|
||||
Message::ImportMnemonic(recover) => self.recover = recover,
|
||||
Message::Skip => {
|
||||
self.skip = true;
|
||||
return Command::perform(async {}, |_| Message::Next);
|
||||
return Task::perform(async {}, |_| Message::Next);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
|
||||
fn apply(&mut self, ctx: &mut Context) -> bool {
|
||||
|
||||
@ -22,7 +22,7 @@ pub use share_xpubs::ShareXpubs;
|
||||
|
||||
use std::path::PathBuf;
|
||||
|
||||
use iced::{Command, Subscription};
|
||||
use iced::{Subscription, Task};
|
||||
|
||||
use liana_ui::widget::*;
|
||||
|
||||
@ -33,8 +33,8 @@ use crate::{
|
||||
};
|
||||
|
||||
pub trait Step {
|
||||
fn update(&mut self, _hws: &mut HardwareWallets, _message: Message) -> Command<Message> {
|
||||
Command::none()
|
||||
fn update(&mut self, _hws: &mut HardwareWallets, _message: Message) -> Task<Message> {
|
||||
Task::none()
|
||||
}
|
||||
fn subscription(&self, _hws: &HardwareWallets) -> Subscription<Message> {
|
||||
Subscription::none()
|
||||
@ -47,8 +47,8 @@ pub trait Step {
|
||||
) -> Element<'a, Message>;
|
||||
|
||||
fn load_context(&mut self, _ctx: &Context) {}
|
||||
fn load(&self) -> Command<Message> {
|
||||
Command::none()
|
||||
fn load(&self) -> Task<Message> {
|
||||
Task::none()
|
||||
}
|
||||
fn skip(&self, _ctx: &Context) -> bool {
|
||||
false
|
||||
@ -88,14 +88,14 @@ impl Step for Final {
|
||||
fn load_context(&mut self, ctx: &Context) {
|
||||
self.internal_bitcoind.clone_from(&ctx.internal_bitcoind);
|
||||
}
|
||||
fn load(&self) -> Command<Message> {
|
||||
fn load(&self) -> Task<Message> {
|
||||
if !self.generating && self.config_path.is_none() {
|
||||
Command::perform(async {}, |_| Message::Install)
|
||||
Task::perform(async {}, |_| Message::Install)
|
||||
} else {
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
}
|
||||
fn update(&mut self, _hws: &mut HardwareWallets, message: Message) -> Command<Message> {
|
||||
fn update(&mut self, _hws: &mut HardwareWallets, message: Message) -> Task<Message> {
|
||||
match message {
|
||||
Message::Installed(res) => {
|
||||
self.generating = false;
|
||||
@ -107,9 +107,11 @@ impl Step for Final {
|
||||
Ok(path) => {
|
||||
self.config_path = Some(path.clone());
|
||||
let internal_bitcoind = self.internal_bitcoind.clone();
|
||||
return Command::perform(async {}, move |_| {
|
||||
Message::Exit(path.clone(), internal_bitcoind)
|
||||
});
|
||||
let path = path.clone();
|
||||
return Task::perform(
|
||||
async { (path, internal_bitcoind) },
|
||||
|(path, internal_bitcoind)| Message::Exit(path, internal_bitcoind),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -120,7 +122,7 @@ impl Step for Final {
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
|
||||
fn view<'a>(
|
||||
|
||||
@ -7,7 +7,7 @@ use std::str::FromStr;
|
||||
use bitcoin_hashes::{sha256, Hash};
|
||||
#[cfg(any(target_os = "macos", target_os = "linux"))]
|
||||
use flate2::read::GzDecoder;
|
||||
use iced::{Command, Subscription};
|
||||
use iced::{Subscription, Task};
|
||||
use liana::miniscript::bitcoin::Network;
|
||||
use lianad::config::{BitcoinBackend, BitcoindConfig, BitcoindRpcAuth};
|
||||
#[cfg(any(target_os = "macos", target_os = "linux"))]
|
||||
@ -303,16 +303,16 @@ impl Step for SelectBitcoindTypeStep {
|
||||
fn skip(&self, ctx: &Context) -> bool {
|
||||
ctx.remote_backend.is_some()
|
||||
}
|
||||
fn update(&mut self, _hws: &mut HardwareWallets, message: Message) -> Command<Message> {
|
||||
fn update(&mut self, _hws: &mut HardwareWallets, message: Message) -> Task<Message> {
|
||||
if let Message::SelectBitcoindType(msg) = message {
|
||||
match msg {
|
||||
message::SelectBitcoindTypeMsg::UseExternal(selected) => {
|
||||
self.use_external = selected;
|
||||
}
|
||||
};
|
||||
return Command::perform(async {}, |_| Message::Next);
|
||||
return Task::perform(async {}, |_| Message::Next);
|
||||
};
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
|
||||
fn apply(&mut self, ctx: &mut Context) -> bool {
|
||||
@ -410,7 +410,7 @@ impl DefineBitcoind {
|
||||
self.network = Some(ctx.bitcoin_config.network);
|
||||
}
|
||||
|
||||
pub fn update(&mut self, message: message::DefineNode) -> Command<Message> {
|
||||
pub fn update(&mut self, message: message::DefineNode) -> Task<Message> {
|
||||
if let message::DefineNode::DefineBitcoind(msg) = message {
|
||||
match msg {
|
||||
message::DefineBitcoind::ConfigFieldEdited(field, value) => match field {
|
||||
@ -443,7 +443,7 @@ impl DefineBitcoind {
|
||||
}
|
||||
};
|
||||
};
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
|
||||
pub fn apply(&mut self, ctx: &mut Context) -> bool {
|
||||
@ -552,7 +552,7 @@ impl Step for InternalBitcoindStep {
|
||||
}
|
||||
}
|
||||
}
|
||||
fn update(&mut self, _hws: &mut HardwareWallets, message: Message) -> Command<Message> {
|
||||
fn update(&mut self, _hws: &mut HardwareWallets, message: Message) -> Task<Message> {
|
||||
if let Message::InternalBitcoind(msg) = message {
|
||||
match msg {
|
||||
message::InternalBitcoindMsg::Previous => {
|
||||
@ -568,7 +568,7 @@ impl Step for InternalBitcoindStep {
|
||||
}
|
||||
}
|
||||
self.started = None; // clear both Ok and Err
|
||||
return Command::perform(async {}, |_| Message::Previous);
|
||||
return Task::perform(async {}, |_| Message::Previous);
|
||||
}
|
||||
message::InternalBitcoindMsg::Reload => {
|
||||
return self.load();
|
||||
@ -583,7 +583,7 @@ impl Step for InternalBitcoindStep {
|
||||
}
|
||||
Err(e) => {
|
||||
self.error = Some(e.to_string());
|
||||
return Command::none();
|
||||
return Task::none();
|
||||
}
|
||||
};
|
||||
let (rpc_port, p2p_port) = if let Some(network_conf) =
|
||||
@ -599,18 +599,18 @@ impl Step for InternalBitcoindStep {
|
||||
"Could not get distinct ports. Please try again."
|
||||
.to_string(),
|
||||
);
|
||||
return Command::none();
|
||||
return Task::none();
|
||||
}
|
||||
(rpc_port, p2p_port)
|
||||
}
|
||||
(Ok(_), Err(e)) | (Err(e), Ok(_)) => {
|
||||
self.error = Some(format!("Could not get available port: {}.", e));
|
||||
return Command::none();
|
||||
return Task::none();
|
||||
}
|
||||
(Err(e1), Err(e2)) => {
|
||||
self.error =
|
||||
Some(format!("Could not get available ports: {}; {}.", e1, e2));
|
||||
return Command::none();
|
||||
return Task::none();
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -618,7 +618,7 @@ impl Step for InternalBitcoindStep {
|
||||
Ok((rpc_auth, password)) => (rpc_auth, password),
|
||||
Err(e) => {
|
||||
self.error = Some(e.to_string());
|
||||
return Command::none();
|
||||
return Task::none();
|
||||
}
|
||||
};
|
||||
let bitcoind_config = BitcoindConfig {
|
||||
@ -637,12 +637,12 @@ impl Step for InternalBitcoindStep {
|
||||
&self.bitcoind_datadir,
|
||||
)) {
|
||||
self.error = Some(e.to_string());
|
||||
return Command::none();
|
||||
return Task::none();
|
||||
};
|
||||
self.error = None;
|
||||
self.internal_bitcoind_config = Some(conf);
|
||||
self.bitcoind_config = Some(bitcoind_config);
|
||||
return Command::perform(async {}, |_| {
|
||||
return Task::perform(async {}, |_| {
|
||||
Message::InternalBitcoind(message::InternalBitcoindMsg::Reload)
|
||||
});
|
||||
}
|
||||
@ -659,7 +659,7 @@ impl Step for InternalBitcoindStep {
|
||||
download.progress(progress);
|
||||
if let DownloadState::Finished(_) = &download.state {
|
||||
info!("Download of bitcoind complete.");
|
||||
return Command::perform(async {}, |_| {
|
||||
return Task::perform(async {}, |_| {
|
||||
Message::InternalBitcoind(message::InternalBitcoindMsg::Install)
|
||||
});
|
||||
}
|
||||
@ -681,7 +681,7 @@ impl Step for InternalBitcoindStep {
|
||||
&self.liana_datadir,
|
||||
VERSION,
|
||||
));
|
||||
return Command::perform(async {}, |_| {
|
||||
return Task::perform(async {}, |_| {
|
||||
Message::InternalBitcoind(
|
||||
message::InternalBitcoindMsg::Start,
|
||||
)
|
||||
@ -691,7 +691,7 @@ impl Step for InternalBitcoindStep {
|
||||
info!("Installation of bitcoind failed.");
|
||||
self.install_state = Some(InstallState::Errored(e.clone()));
|
||||
self.error = Some(e.to_string());
|
||||
return Command::none();
|
||||
return Task::none();
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -702,7 +702,7 @@ impl Step for InternalBitcoindStep {
|
||||
self.started = Some(Err(
|
||||
StartInternalBitcoindError::CouldNotCanonicalizeDataDir(e.to_string()),
|
||||
));
|
||||
return Command::none();
|
||||
return Task::none();
|
||||
};
|
||||
let bitcoind_config = self
|
||||
.bitcoind_config
|
||||
@ -713,7 +713,7 @@ impl Step for InternalBitcoindStep {
|
||||
Err(e) => {
|
||||
self.started =
|
||||
Some(Err(StartInternalBitcoindError::CommandError(e.to_string())));
|
||||
return Command::none();
|
||||
return Task::none();
|
||||
}
|
||||
Ok(bitcoind) => {
|
||||
self.error = None;
|
||||
@ -724,7 +724,7 @@ impl Step for InternalBitcoindStep {
|
||||
}
|
||||
};
|
||||
};
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
|
||||
fn subscription(&self, _hws: &HardwareWallets) -> Subscription<Message> {
|
||||
@ -734,25 +734,25 @@ impl Step for InternalBitcoindStep {
|
||||
Subscription::none()
|
||||
}
|
||||
|
||||
fn load(&self) -> Command<Message> {
|
||||
fn load(&self) -> Task<Message> {
|
||||
if self.internal_bitcoind_config.is_none() {
|
||||
return Command::perform(async {}, |_| {
|
||||
return Task::perform(async {}, |_| {
|
||||
Message::InternalBitcoind(message::InternalBitcoindMsg::DefineConfig)
|
||||
});
|
||||
}
|
||||
if let Some(download) = &self.exe_download {
|
||||
if let DownloadState::Idle = download.state {
|
||||
return Command::perform(async {}, |_| {
|
||||
return Task::perform(async {}, |_| {
|
||||
Message::InternalBitcoind(message::InternalBitcoindMsg::Download)
|
||||
});
|
||||
}
|
||||
}
|
||||
if self.started.is_none() {
|
||||
return Command::perform(async {}, |_| {
|
||||
return Task::perform(async {}, |_| {
|
||||
Message::InternalBitcoind(message::InternalBitcoindMsg::Start)
|
||||
});
|
||||
}
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
|
||||
fn apply(&mut self, ctx: &mut Context) -> bool {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
use iced::Command;
|
||||
use iced::Task;
|
||||
use liana_ui::{component::form, widget::*};
|
||||
use lianad::{
|
||||
config::ElectrumConfig,
|
||||
@ -28,7 +28,7 @@ impl DefineElectrum {
|
||||
!self.address.value.is_empty() && self.address.valid
|
||||
}
|
||||
|
||||
pub fn update(&mut self, message: message::DefineNode) -> Command<Message> {
|
||||
pub fn update(&mut self, message: message::DefineNode) -> Task<Message> {
|
||||
if let message::DefineNode::DefineElectrum(msg) = message {
|
||||
match msg {
|
||||
message::DefineElectrum::ConfigFieldEdited(field, value) => match field {
|
||||
@ -40,7 +40,7 @@ impl DefineElectrum {
|
||||
},
|
||||
};
|
||||
};
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
|
||||
pub fn apply(&mut self, ctx: &mut Context) -> bool {
|
||||
|
||||
@ -15,7 +15,7 @@ use crate::{
|
||||
node::NodeType,
|
||||
};
|
||||
|
||||
use iced::Command;
|
||||
use iced::Task;
|
||||
use liana_ui::widget::Element;
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -62,7 +62,7 @@ impl NodeDefinition {
|
||||
}
|
||||
}
|
||||
|
||||
fn update(&mut self, message: message::DefineNode) -> Command<Message> {
|
||||
fn update(&mut self, message: message::DefineNode) -> Task<Message> {
|
||||
match self {
|
||||
NodeDefinition::Bitcoind(def) => def.update(message),
|
||||
NodeDefinition::Electrum(def) => def.update(message),
|
||||
@ -154,11 +154,7 @@ impl DefineNode {
|
||||
.find(|node| node.definition.node_type() == node_type)
|
||||
}
|
||||
|
||||
fn update_node(
|
||||
&mut self,
|
||||
node_type: NodeType,
|
||||
message: message::DefineNode,
|
||||
) -> Command<Message> {
|
||||
fn update_node(&mut self, node_type: NodeType, message: message::DefineNode) -> Task<Message> {
|
||||
if let Some(node) = self.get_mut(node_type) {
|
||||
// Don't make changes while waiting for a ping result so that we
|
||||
// know which values the ping result applies to.
|
||||
@ -167,7 +163,7 @@ impl DefineNode {
|
||||
return node.definition.update(message);
|
||||
}
|
||||
}
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
}
|
||||
|
||||
@ -183,7 +179,7 @@ impl Step for DefineNode {
|
||||
node.definition.load_context(ctx);
|
||||
}
|
||||
}
|
||||
fn update(&mut self, _hws: &mut HardwareWallets, message: Message) -> Command<Message> {
|
||||
fn update(&mut self, _hws: &mut HardwareWallets, message: Message) -> Task<Message> {
|
||||
if let Message::DefineNode(msg) = message {
|
||||
match msg {
|
||||
message::DefineNode::NodeTypeSelected(node_type) => {
|
||||
@ -198,7 +194,7 @@ impl Step for DefineNode {
|
||||
selected.is_running = None;
|
||||
let def = selected.definition.clone();
|
||||
let node_type = def.node_type();
|
||||
return Command::perform(async move { def.ping() }, move |res| {
|
||||
return Task::perform(async move { def.ping() }, move |res| {
|
||||
Message::DefineNode(message::DefineNode::PingResult((node_type, res)))
|
||||
});
|
||||
}
|
||||
@ -222,7 +218,7 @@ impl Step for DefineNode {
|
||||
}
|
||||
}
|
||||
}
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
|
||||
fn apply(&mut self, ctx: &mut Context) -> bool {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use iced::{Command, Subscription};
|
||||
use iced::{Subscription, Task};
|
||||
use liana::miniscript::bitcoin::{
|
||||
bip32::{ChildNumber, Fingerprint},
|
||||
Network,
|
||||
@ -85,7 +85,7 @@ impl ShareXpubs {
|
||||
impl Step for ShareXpubs {
|
||||
// form value is set as valid each time it is edited.
|
||||
// Verification of the values is happening when the user click on Next button.
|
||||
fn update(&mut self, hws: &mut HardwareWallets, message: Message) -> Command<Message> {
|
||||
fn update(&mut self, hws: &mut HardwareWallets, message: Message) -> Task<Message> {
|
||||
match message {
|
||||
Message::ImportXpub(fg, res) => {
|
||||
if let Some(hw_xpubs) = self.hw_xpubs.iter_mut().find(|x| x.fingerprint == fg) {
|
||||
@ -133,7 +133,7 @@ impl Step for ShareXpubs {
|
||||
error: None,
|
||||
});
|
||||
}
|
||||
return Command::perform(
|
||||
return Task::perform(
|
||||
async move {
|
||||
(
|
||||
fingerprint,
|
||||
@ -146,7 +146,7 @@ impl Step for ShareXpubs {
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
|
||||
fn subscription(&self, hws: &HardwareWallets) -> Subscription<Message> {
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
#![allow(deprecated)]
|
||||
|
||||
pub mod template;
|
||||
|
||||
use iced::widget::{container, pick_list, scrollable, slider, Button, Space};
|
||||
@ -7,6 +9,7 @@ use liana::miniscript::bitcoin::Network;
|
||||
use liana_ui::component::text::{self, h3, p1_bold, p2_regular, H3_SIZE};
|
||||
use liana_ui::image;
|
||||
use std::borrow::Cow;
|
||||
use std::fmt::Display;
|
||||
use std::str::FromStr;
|
||||
|
||||
use liana::miniscript::bitcoin::{self, bip32::Fingerprint};
|
||||
@ -62,7 +65,7 @@ pub fn define_descriptor_advanced_settings<'a>(use_taproot: bool) -> Element<'a,
|
||||
}),
|
||||
|kind| Message::CreateTaprootDescriptor(kind == DescriptorKind::Taproot),
|
||||
)
|
||||
.style(theme::PickList::Secondary)
|
||||
.style(theme::pick_list::primary)
|
||||
.padding(10),
|
||||
));
|
||||
|
||||
@ -75,7 +78,7 @@ pub fn define_descriptor_advanced_settings<'a>(use_taproot: bool) -> Element<'a,
|
||||
.push_maybe(if use_taproot {
|
||||
Some(
|
||||
p1_regular("Taproot is only supported by Liana version 5.0 and above")
|
||||
.style(color::GREY_2),
|
||||
.color(color::GREY_2),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
@ -102,7 +105,7 @@ pub fn path(
|
||||
.push(
|
||||
Column::new()
|
||||
.spacing(5)
|
||||
.align_items(Alignment::Center)
|
||||
.align_x(Alignment::Center)
|
||||
.push(Column::with_children(keys).spacing(5)),
|
||||
)
|
||||
.push_maybe(if fixed {
|
||||
@ -124,22 +127,22 @@ pub fn path(
|
||||
}),
|
||||
)
|
||||
.padding(10)
|
||||
.style(theme::Container::Card(theme::Card::Border))
|
||||
.style(theme::card::border)
|
||||
.into()
|
||||
}
|
||||
|
||||
pub fn uneditable_defined_key<'a>(
|
||||
alias: &'a str,
|
||||
color: iced::Color,
|
||||
title: impl Into<Cow<'a, str>>,
|
||||
title: impl Into<Cow<'a, str>> + std::fmt::Display,
|
||||
warning: Option<&'static str>,
|
||||
) -> Element<'a, message::DefineKey> {
|
||||
card::simple(
|
||||
Row::new()
|
||||
.spacing(10)
|
||||
.width(Length::Fill)
|
||||
.align_items(Alignment::Center)
|
||||
.push(icon::round_key_icon().size(H3_SIZE).style(color))
|
||||
.align_y(Alignment::Center)
|
||||
.push(icon::round_key_icon().size(H3_SIZE).color(color))
|
||||
.push(
|
||||
Column::new()
|
||||
.width(Length::Fill)
|
||||
@ -147,13 +150,13 @@ pub fn uneditable_defined_key<'a>(
|
||||
.push(
|
||||
Row::new()
|
||||
.spacing(10)
|
||||
.push(p1_regular(title).style(color::GREY_2))
|
||||
.push(p1_regular(title).color(color::GREY_2))
|
||||
.push(p1_bold(alias)),
|
||||
)
|
||||
.push_maybe(warning.map(|w| p2_regular(w).style(color::RED))),
|
||||
.push_maybe(warning.map(|w| p2_regular(w).color(color::RED))),
|
||||
)
|
||||
.push_maybe(if warning.is_none() {
|
||||
Some(icon::check_icon().style(color::GREEN))
|
||||
Some(icon::check_icon().color(color::GREEN))
|
||||
} else {
|
||||
None
|
||||
}),
|
||||
@ -164,7 +167,7 @@ pub fn uneditable_defined_key<'a>(
|
||||
pub fn defined_key<'a>(
|
||||
alias: &'a str,
|
||||
color: iced::Color,
|
||||
title: impl Into<Cow<'a, str>>,
|
||||
title: impl Display,
|
||||
warning: Option<&'static str>,
|
||||
fixed: bool,
|
||||
) -> Element<'a, message::DefineKey> {
|
||||
@ -172,8 +175,8 @@ pub fn defined_key<'a>(
|
||||
Row::new()
|
||||
.spacing(10)
|
||||
.width(Length::Fill)
|
||||
.align_items(Alignment::Center)
|
||||
.push(icon::round_key_icon().size(H3_SIZE).style(color))
|
||||
.align_y(Alignment::Center)
|
||||
.push(icon::round_key_icon().size(H3_SIZE).color(color))
|
||||
.push(
|
||||
Column::new()
|
||||
.width(Length::Fill)
|
||||
@ -181,13 +184,13 @@ pub fn defined_key<'a>(
|
||||
.push(
|
||||
Row::new()
|
||||
.spacing(10)
|
||||
.push(p1_regular(title).style(color::GREY_2))
|
||||
.push(p1_regular(format!("{}", title)).color(color::GREY_2))
|
||||
.push(p1_bold(alias)),
|
||||
)
|
||||
.push_maybe(warning.map(|w| p2_regular(w).style(color::RED))),
|
||||
.push_maybe(warning.map(|w| p2_regular(w).color(color::RED))),
|
||||
)
|
||||
.push_maybe(if warning.is_none() {
|
||||
Some(icon::check_icon().style(color::GREEN))
|
||||
Some(icon::check_icon().color(color::GREEN))
|
||||
} else {
|
||||
None
|
||||
})
|
||||
@ -200,7 +203,7 @@ pub fn defined_key<'a>(
|
||||
} else {
|
||||
Some(
|
||||
Button::new(icon::trash_icon())
|
||||
.style(theme::Button::Secondary)
|
||||
.style(theme::button::secondary)
|
||||
.padding(5)
|
||||
.on_press(message::DefineKey::Delete),
|
||||
)
|
||||
@ -211,7 +214,7 @@ pub fn defined_key<'a>(
|
||||
|
||||
pub fn undefined_key<'a>(
|
||||
color: iced::Color,
|
||||
title: impl Into<Cow<'a, str>>,
|
||||
title: impl Into<Cow<'a, str>> + std::fmt::Display,
|
||||
active: bool,
|
||||
fixed: bool,
|
||||
) -> Element<'a, message::DefineKey> {
|
||||
@ -219,8 +222,8 @@ pub fn undefined_key<'a>(
|
||||
Row::new()
|
||||
.spacing(10)
|
||||
.width(Length::Fill)
|
||||
.align_items(Alignment::Center)
|
||||
.push(icon::round_key_icon().size(H3_SIZE).style(color))
|
||||
.align_y(Alignment::Center)
|
||||
.push(icon::round_key_icon().size(H3_SIZE).color(color))
|
||||
.push(
|
||||
Column::new()
|
||||
.width(Length::Fill)
|
||||
@ -240,7 +243,7 @@ pub fn undefined_key<'a>(
|
||||
} else {
|
||||
Some(
|
||||
Button::new(icon::trash_icon())
|
||||
.style(theme::Button::Secondary)
|
||||
.style(theme::button::secondary)
|
||||
.padding(5)
|
||||
.on_press(message::DefineKey::Delete),
|
||||
)
|
||||
@ -274,7 +277,7 @@ pub fn edit_key_modal<'a>(
|
||||
.push(h3(title))
|
||||
.push(Space::with_width(Length::Fill))
|
||||
.push(button::transparent(Some(icon::cross_icon().size(40)), "").on_press(Message::Close))
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
)
|
||||
.push(
|
||||
Column::new()
|
||||
@ -294,14 +297,14 @@ pub fn edit_key_modal<'a>(
|
||||
})
|
||||
.width(Length::Fill)
|
||||
.on_press(Message::UseHotSigner)
|
||||
.style(theme::Button::Border),
|
||||
.style(theme::button::container_border),
|
||||
)
|
||||
.push(if manually_imported_xpub {
|
||||
card::simple(Column::new()
|
||||
.spacing(10)
|
||||
.push(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.push(p1_regular("Enter an extended public key:").width(Length::Fill))
|
||||
.push(image::success_mark_icon().width(Length::Fixed(50.0)))
|
||||
)
|
||||
@ -329,7 +332,7 @@ pub fn edit_key_modal<'a>(
|
||||
Container::new(
|
||||
Button::new(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.spacing(10)
|
||||
.push(icon::import_icon())
|
||||
.push(p1_regular("Enter an extended public key"))
|
||||
@ -339,7 +342,7 @@ pub fn edit_key_modal<'a>(
|
||||
.on_press(Message::DefineDescriptor(
|
||||
message::DefineDescriptor::KeyModal(message::ImportKeyModal::ManuallyImportXpub)
|
||||
))
|
||||
.style(theme::Button::Secondary),
|
||||
.style(theme::button::secondary),
|
||||
)
|
||||
}
|
||||
)
|
||||
@ -355,7 +358,7 @@ pub fn edit_key_modal<'a>(
|
||||
.push(text("Key name:").bold())
|
||||
.push(tooltip(prompt::DEFINE_DESCRIPTOR_FINGERPRINT_TOOLTIP)),
|
||||
)
|
||||
.push(p1_regular("Give this key a friendly name. It helps you identify it later").style(color::GREY_2))
|
||||
.push(p1_regular("Give this key a friendly name. It helps you identify it later").color(color::GREY_2))
|
||||
.push(
|
||||
form::Form::new("Name", form_name, |msg| {
|
||||
Message::DefineDescriptor(message::DefineDescriptor::KeyModal(
|
||||
@ -372,7 +375,7 @@ pub fn edit_key_modal<'a>(
|
||||
)
|
||||
.push_maybe(
|
||||
if duplicate_master_fg {
|
||||
Some(text("A single signing device may not be used more than once per path. (It can still be used in other paths.)").style(color::RED))
|
||||
Some(text("A single signing device may not be used more than once per path. (It can still be used in other paths.)").color(color::RED))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
@ -390,7 +393,7 @@ pub fn edit_key_modal<'a>(
|
||||
} else {None})
|
||||
.width(Length::Fixed(200.0))
|
||||
)
|
||||
.align_items(Alignment::Center),
|
||||
.align_x(Alignment::Center),
|
||||
))
|
||||
.width(Length::Fixed(800.0));
|
||||
scrollable(content).into()
|
||||
@ -421,7 +424,7 @@ pub fn edit_sequence_modal<'a>(sequence: &form::Value<String>) -> Element<'a, Me
|
||||
let mut col = Column::new()
|
||||
.width(Length::Fill)
|
||||
.spacing(20)
|
||||
.align_items(Alignment::Center)
|
||||
.align_x(Alignment::Center)
|
||||
.push(text("Keys can move the funds after inactivity of:"))
|
||||
.push(
|
||||
Row::new()
|
||||
@ -502,7 +505,7 @@ pub fn edit_threshold_modal<'a>(threshold: (usize, usize)) -> Element<'a, Messag
|
||||
Column::new()
|
||||
.width(Length::Fill)
|
||||
.spacing(20)
|
||||
.align_items(Alignment::Center)
|
||||
.align_x(Alignment::Center)
|
||||
.push(threshsold_input::threshsold_input(
|
||||
threshold.0,
|
||||
threshold.1,
|
||||
@ -592,7 +595,7 @@ mod threshsold_input {
|
||||
fn view(&self, _state: &Self::State) -> Element<Self::Event> {
|
||||
let button = |label, on_press| {
|
||||
Button::new(label)
|
||||
.style(theme::Button::Transparent)
|
||||
.style(theme::button::transparent)
|
||||
.width(Length::Fixed(50.0))
|
||||
.on_press(on_press)
|
||||
};
|
||||
@ -606,7 +609,7 @@ mod threshsold_input {
|
||||
.align_y(alignment::Vertical::Center),
|
||||
)
|
||||
.push(button(icon::down_icon().size(30), Event::DecrementPressed))
|
||||
.align_items(Alignment::Center)
|
||||
.align_x(Alignment::Center)
|
||||
.into()
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,18 +25,18 @@ pub fn custom_template_description(progress: (usize, usize)) -> Element<'static,
|
||||
None,
|
||||
"Introduction",
|
||||
Column::new()
|
||||
.align_items(Alignment::Start)
|
||||
.align_x(Alignment::Start)
|
||||
.push(h3("Build your own"))
|
||||
.max_width(800.0)
|
||||
.push(Container::new(
|
||||
p1_regular("For this setup you will need to define your primary and recovery spending policies. For security reasons, we suggest you use a separate Hardware Wallet for each key belonging to them.")
|
||||
.style(color::GREY_2)
|
||||
.horizontal_alignment(alignment::Horizontal::Left)
|
||||
.color(color::GREY_2)
|
||||
.align_x(alignment::Horizontal::Left)
|
||||
).align_x(alignment::Horizontal::Left).width(Length::Fill))
|
||||
.push(Container::new(
|
||||
p1_regular("The keys belonging to your primary policy can always spend. Those belonging to the recovery policies will be able to spend only after a defined time of wallet inactivity, allowing for secure recovery and advanced spending policies.")
|
||||
.style(color::GREY_2)
|
||||
.horizontal_alignment(alignment::Horizontal::Left)
|
||||
.color(color::GREY_2)
|
||||
.align_x(alignment::Horizontal::Left)
|
||||
).align_x(alignment::Horizontal::Left).width(Length::Fill))
|
||||
.push(image::custom_template_description().width(Length::Fill))
|
||||
.push(Row::new().push(Space::with_width(Length::Fill)).push(button::primary(None, "Next").width(Length::Fixed(200.0)).on_press(Message::Next)))
|
||||
@ -66,28 +66,28 @@ pub fn custom_template<'a>(
|
||||
None,
|
||||
"Set keys",
|
||||
Column::new()
|
||||
.align_items(Alignment::Start)
|
||||
.align_x(Alignment::Start)
|
||||
.max_width(1000.0)
|
||||
.push(collapse::Collapse::new(
|
||||
|| {
|
||||
Button::new(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.spacing(10)
|
||||
.push(text("Advanced settings").small().bold())
|
||||
.push(icon::collapse_icon()),
|
||||
)
|
||||
.style(theme::Button::Transparent)
|
||||
.style(theme::button::transparent)
|
||||
},
|
||||
|| {
|
||||
Button::new(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.spacing(10)
|
||||
.push(text("Advanced settings").small().bold())
|
||||
.push(icon::collapsed_icon()),
|
||||
)
|
||||
.style(theme::Button::Transparent)
|
||||
.style(theme::button::transparent)
|
||||
},
|
||||
move || define_descriptor_advanced_settings(use_taproot),
|
||||
))
|
||||
|
||||
@ -26,34 +26,34 @@ pub fn inheritance_template_description(progress: (usize, usize)) -> Element<'st
|
||||
None,
|
||||
"Introduction",
|
||||
Column::new()
|
||||
.align_items(Alignment::Start)
|
||||
.align_x(Alignment::Start)
|
||||
.push(h3("Simple inheritance wallet"))
|
||||
.max_width(800.0)
|
||||
.push(Container::new(
|
||||
p1_regular("For this setup you will need 2 Keys: Your Primary Key (for yourself) and an Inheritance Key (for your heir). For security reasons, we suggest you use a separate Hardware Wallet for each key.")
|
||||
.style(color::GREY_2)
|
||||
.horizontal_alignment(alignment::Horizontal::Left)
|
||||
.color(color::GREY_2)
|
||||
.align_x(alignment::Horizontal::Left)
|
||||
).align_x(alignment::Horizontal::Left).width(Length::Fill))
|
||||
.push(Row::new()
|
||||
.spacing(30)
|
||||
.push(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.spacing(10)
|
||||
.push(icon::round_key_icon().size(H3_SIZE).style(color::GREEN))
|
||||
.push(icon::round_key_icon().size(H3_SIZE).color(color::GREEN))
|
||||
.push(p1_regular("Primary key").bold())
|
||||
).push(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.spacing(10)
|
||||
.push(icon::round_key_icon().size(H3_SIZE).style(color::WHITE))
|
||||
.push(icon::round_key_icon().size(H3_SIZE).color(color::WHITE))
|
||||
.push(p1_regular("Inheritance key").bold())
|
||||
))
|
||||
.push(Container::new(
|
||||
p1_regular("You will always be able to spend using your Primary Key.
|
||||
After a period of inactivity (but not before that) your Inheritance Key will become able to recover your funds.")
|
||||
.style(color::GREY_2)
|
||||
.horizontal_alignment(alignment::Horizontal::Left)
|
||||
.color(color::GREY_2)
|
||||
.align_x(alignment::Horizontal::Left)
|
||||
).align_x(alignment::Horizontal::Left).width(Length::Fill))
|
||||
.push(image::inheritance_template_description().width(Length::Fill))
|
||||
.push(Row::new().push(Space::with_width(Length::Fill)).push(button::primary(None, "Next").width(Length::Fixed(200.0)).on_press(Message::Next)))
|
||||
@ -77,28 +77,28 @@ pub fn inheritance_template<'a>(
|
||||
None,
|
||||
"Set keys",
|
||||
Column::new()
|
||||
.align_items(Alignment::Start)
|
||||
.align_x(Alignment::Start)
|
||||
.max_width(1000.0)
|
||||
.push(collapse::Collapse::new(
|
||||
|| {
|
||||
Button::new(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.spacing(10)
|
||||
.push(text("Advanced settings").small().bold())
|
||||
.push(icon::collapse_icon()),
|
||||
)
|
||||
.style(theme::Button::Transparent)
|
||||
.style(theme::button::transparent)
|
||||
},
|
||||
|| {
|
||||
Button::new(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.spacing(10)
|
||||
.push(text("Advanced settings").small().bold())
|
||||
.push(icon::collapsed_icon()),
|
||||
)
|
||||
.style(theme::Button::Transparent)
|
||||
.style(theme::button::transparent)
|
||||
},
|
||||
move || define_descriptor_advanced_settings(use_taproot),
|
||||
))
|
||||
|
||||
@ -21,13 +21,13 @@ pub fn choose_descriptor_template(progress: (usize, usize)) -> Element<'static,
|
||||
"Choose wallet type",
|
||||
Column::new()
|
||||
.max_width(800.0)
|
||||
.align_items(Alignment::Start)
|
||||
.align_x(Alignment::Start)
|
||||
.push(
|
||||
Button::new(
|
||||
Column::new()
|
||||
.align_items(Alignment::Start)
|
||||
.align_x(Alignment::Start)
|
||||
.push(h3("Simple inheritance"))
|
||||
.push(p2_regular("Two keys required, one for yourself to spend and another for your heir.").style(color::GREY_2))
|
||||
.push(p2_regular("Two keys required, one for yourself to spend and another for your heir.").color(color::GREY_2))
|
||||
.width(Length::Fill)
|
||||
)
|
||||
.padding(15)
|
||||
@ -35,15 +35,15 @@ pub fn choose_descriptor_template(progress: (usize, usize)) -> Element<'static,
|
||||
Message::SelectDescriptorTemplate(
|
||||
context::DescriptorTemplate::SimpleInheritance,
|
||||
)
|
||||
).style(theme::Button::Secondary)
|
||||
).style(theme::button::secondary)
|
||||
.width(Length::Fill),
|
||||
)
|
||||
.push(
|
||||
Button::new(
|
||||
Column::new()
|
||||
.align_items(Alignment::Start)
|
||||
.align_x(Alignment::Start)
|
||||
.push(h3("Expanding multisig"))
|
||||
.push(p2_regular("Two keys required to spend, with an extra key as a backup.").style(color::GREY_2))
|
||||
.push(p2_regular("Two keys required to spend, with an extra key as a backup.").color(color::GREY_2))
|
||||
.width(Length::Fill)
|
||||
)
|
||||
.padding(15)
|
||||
@ -51,15 +51,15 @@ pub fn choose_descriptor_template(progress: (usize, usize)) -> Element<'static,
|
||||
Message::SelectDescriptorTemplate(
|
||||
context::DescriptorTemplate::MultisigSecurity,
|
||||
)
|
||||
).style(theme::Button::Secondary)
|
||||
).style(theme::button::secondary)
|
||||
.width(Length::Fill),
|
||||
)
|
||||
.push(
|
||||
Button::new(
|
||||
Column::new()
|
||||
.align_items(Alignment::Start)
|
||||
.align_x(Alignment::Start)
|
||||
.push(h3("Build your own"))
|
||||
.push(p2_regular("Create a custom setup that fits all your needs.").style(color::GREY_2))
|
||||
.push(p2_regular("Create a custom setup that fits all your needs.").color(color::GREY_2))
|
||||
.width(Length::Fill)
|
||||
)
|
||||
.padding(15)
|
||||
@ -67,7 +67,7 @@ pub fn choose_descriptor_template(progress: (usize, usize)) -> Element<'static,
|
||||
Message::SelectDescriptorTemplate(
|
||||
context::DescriptorTemplate::Custom,
|
||||
)
|
||||
).style(theme::Button::Secondary)
|
||||
).style(theme::button::secondary)
|
||||
.width(Length::Fill),
|
||||
)
|
||||
.spacing(20),
|
||||
|
||||
@ -31,39 +31,39 @@ pub fn multisig_security_template_description(
|
||||
None,
|
||||
"Introduction",
|
||||
Column::new()
|
||||
.align_items(Alignment::Start)
|
||||
.align_x(Alignment::Start)
|
||||
.push(h3("Expanding multisig wallet"))
|
||||
.max_width(800.0)
|
||||
.push(Container::new(
|
||||
p1_regular("For this setup you will need 3 keys: two Primary Keys and a Recovery Key. For security reasons, we suggest you use a separate Hardware Wallet for each key.")
|
||||
.style(color::GREY_2)
|
||||
.horizontal_alignment(alignment::Horizontal::Left)
|
||||
.color(color::GREY_2)
|
||||
.align_x(alignment::Horizontal::Left)
|
||||
).align_x(alignment::Horizontal::Left).width(Length::Fill))
|
||||
.push(Row::new()
|
||||
.spacing(30)
|
||||
.push(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.spacing(10)
|
||||
.push(icon::round_key_icon().size(H3_SIZE).style(color::GREEN))
|
||||
.push(icon::round_key_icon().size(H3_SIZE).color(color::GREEN))
|
||||
.push(p1_regular("Primary key #1").bold())
|
||||
).push(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.spacing(10)
|
||||
.push(icon::round_key_icon().size(H3_SIZE).style(color::GREEN))
|
||||
.push(icon::round_key_icon().size(H3_SIZE).color(color::GREEN))
|
||||
.push(p1_regular("Primary key #2").bold())
|
||||
).push(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.spacing(10)
|
||||
.push(icon::round_key_icon().size(H3_SIZE).style(color::ORANGE))
|
||||
.push(icon::round_key_icon().size(H3_SIZE).color(color::ORANGE))
|
||||
.push(p1_regular("Recovery key").bold())
|
||||
))
|
||||
.push(Container::new(
|
||||
p1_regular("The Primary Keys will compose a 2-of-2 multisig which will always be able to spend. In case one of your keys becomes unavailable, after a period of inactivity you will be able to recover your funds using the Recovery Key together with one of your Primary Keys (2-of-3 multisig):")
|
||||
.style(color::GREY_2)
|
||||
.horizontal_alignment(alignment::Horizontal::Left)
|
||||
.color(color::GREY_2)
|
||||
.align_x(alignment::Horizontal::Left)
|
||||
).align_x(alignment::Horizontal::Left).width(Length::Fill))
|
||||
.push(image::multisig_security_template_description().width(Length::Fill))
|
||||
.push(Row::new().push(Space::with_width(Length::Fill)).push(button::primary(None, "Next").width(Length::Fixed(200.0)).on_press(Message::Next)))
|
||||
@ -88,28 +88,28 @@ pub fn multisig_security_template<'a>(
|
||||
None,
|
||||
"Set keys",
|
||||
Column::new()
|
||||
.align_items(Alignment::Start)
|
||||
.align_x(Alignment::Start)
|
||||
.max_width(1000.0)
|
||||
.push(collapse::Collapse::new(
|
||||
|| {
|
||||
Button::new(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.spacing(10)
|
||||
.push(text("Advanced settings").small().bold())
|
||||
.push(icon::collapse_icon()),
|
||||
)
|
||||
.style(theme::Button::Transparent)
|
||||
.style(theme::button::transparent)
|
||||
},
|
||||
|| {
|
||||
Button::new(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.spacing(10)
|
||||
.push(text("Advanced settings").small().bold())
|
||||
.push(icon::collapsed_icon()),
|
||||
)
|
||||
.style(theme::Button::Transparent)
|
||||
.style(theme::button::transparent)
|
||||
},
|
||||
move || define_descriptor_advanced_settings(use_taproot),
|
||||
))
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
pub mod editor;
|
||||
|
||||
use async_hwi::utils::extract_keys_and_template;
|
||||
use iced::widget::{checkbox, radio, scrollable, scrollable::Properties, Button, Space, TextInput};
|
||||
use iced::widget::{checkbox, radio, scrollable, scrollable::Scrollbar, Button, Space, TextInput};
|
||||
use iced::{
|
||||
alignment,
|
||||
widget::{progress_bar, tooltip as iced_tooltip},
|
||||
@ -60,7 +60,7 @@ pub fn import_wallet_or_descriptor<'a>(
|
||||
for (i, wallet) in wallets.into_iter().enumerate() {
|
||||
col_wallets = col_wallets.push(
|
||||
Button::new(h5_regular(wallet).width(Length::Fill))
|
||||
.style(theme::Button::Secondary)
|
||||
.style(theme::button::secondary)
|
||||
.padding(10)
|
||||
.on_press(Message::Select(i)),
|
||||
);
|
||||
@ -76,29 +76,29 @@ pub fn import_wallet_or_descriptor<'a>(
|
||||
Button::new(
|
||||
Column::new()
|
||||
.spacing(5)
|
||||
.push(h4_bold("Load a shared wallet").style(color::WHITE))
|
||||
.push(h4_bold("Load a shared wallet").color(color::WHITE))
|
||||
.push(
|
||||
text("If you received an invitation to join a shared wallet")
|
||||
.style(color::GREY_3),
|
||||
.color(color::GREY_3),
|
||||
),
|
||||
)
|
||||
.padding(15)
|
||||
.width(Length::Fill)
|
||||
.style(theme::Button::TransparentBorder)
|
||||
.style(theme::button::transparent_border)
|
||||
},
|
||||
|| {
|
||||
Button::new(
|
||||
Column::new()
|
||||
.spacing(5)
|
||||
.push(h4_bold("Load a shared wallet").style(color::WHITE))
|
||||
.push(h4_bold("Load a shared wallet").color(color::WHITE))
|
||||
.push(
|
||||
text("Type the invitation token you received by email")
|
||||
.style(color::GREY_3),
|
||||
.color(color::GREY_3),
|
||||
),
|
||||
)
|
||||
.padding(15)
|
||||
.width(Length::Fill)
|
||||
.style(theme::Button::TransparentBorder)
|
||||
.style(theme::button::transparent_border)
|
||||
},
|
||||
move || {
|
||||
if let Some(wallet) = invitation_wallet {
|
||||
@ -170,23 +170,23 @@ pub fn import_wallet_or_descriptor<'a>(
|
||||
Button::new(
|
||||
Column::new()
|
||||
.spacing(5)
|
||||
.push(h4_bold("Load a wallet from descriptor").style(color::WHITE))
|
||||
.push(text("Creates a new wallet from the descriptor").style(color::GREY_3)),
|
||||
.push(h4_bold("Load a wallet from descriptor").color(color::WHITE))
|
||||
.push(text("Creates a new wallet from the descriptor").color(color::GREY_3)),
|
||||
)
|
||||
.padding(15)
|
||||
.width(Length::Fill)
|
||||
.style(theme::Button::TransparentBorder)
|
||||
.style(theme::button::transparent_border)
|
||||
},
|
||||
|| {
|
||||
Button::new(
|
||||
Column::new()
|
||||
.spacing(5)
|
||||
.push(h4_bold("Load a wallet from descriptor").style(color::WHITE))
|
||||
.push(text("Creates a new wallet from the descriptor").style(color::GREY_3)),
|
||||
.push(h4_bold("Load a wallet from descriptor").color(color::WHITE))
|
||||
.push(text("Creates a new wallet from the descriptor").color(color::GREY_3)),
|
||||
)
|
||||
.padding(15)
|
||||
.width(Length::Fill)
|
||||
.style(theme::Button::TransparentBorder)
|
||||
.style(theme::button::transparent_border)
|
||||
},
|
||||
move || {
|
||||
Element::<'a, Message>::from(
|
||||
@ -316,17 +316,17 @@ pub fn signer_xpubs<'a>(
|
||||
Column::new()
|
||||
.push(
|
||||
Button::new(
|
||||
Row::new().align_items(Alignment::Center).push(
|
||||
Row::new().align_y(Alignment::Center).push(
|
||||
Column::new()
|
||||
.push(text("Generate a new mnemonic").bold())
|
||||
.push(text(BACKUP_WARNING).small().style(color::ORANGE))
|
||||
.push(text(BACKUP_WARNING).small().color(color::ORANGE))
|
||||
.spacing(5)
|
||||
.width(Length::Fill),
|
||||
),
|
||||
)
|
||||
.on_press(Message::UseHotSigner)
|
||||
.padding(10)
|
||||
.style(theme::Button::TransparentBorder)
|
||||
.style(theme::button::transparent_border)
|
||||
.width(Length::Fill),
|
||||
)
|
||||
.push_maybe(if xpubs.is_empty() {
|
||||
@ -343,7 +343,7 @@ pub fn signer_xpubs<'a>(
|
||||
|acc, (i, w)| {
|
||||
acc.push(
|
||||
Row::new()
|
||||
.align_items(Alignment::End)
|
||||
.align_y(Alignment::End)
|
||||
.push(
|
||||
Container::new(text(format!("#{}", i + 1)).small())
|
||||
.width(Length::Fixed(50.0)),
|
||||
@ -374,12 +374,12 @@ pub fn signer_xpubs<'a>(
|
||||
col.push(
|
||||
Row::new()
|
||||
.spacing(5)
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.push(
|
||||
Container::new(
|
||||
scrollable(Container::new(text(xpub).small()).padding(10))
|
||||
.direction(scrollable::Direction::Horizontal(
|
||||
Properties::new().width(5).scroller_width(5),
|
||||
Scrollbar::new().width(5).scroller_width(5),
|
||||
)),
|
||||
)
|
||||
.width(Length::Fill),
|
||||
@ -398,7 +398,7 @@ pub fn signer_xpubs<'a>(
|
||||
None
|
||||
}),
|
||||
)
|
||||
.style(theme::Container::Card(theme::Card::Simple))
|
||||
.style(theme::card::simple)
|
||||
.into()
|
||||
}
|
||||
|
||||
@ -448,7 +448,7 @@ pub fn hardware_wallet_xpubs<'a>(
|
||||
kind, pairing_code, ..
|
||||
} => hw::locked_hardware_wallet(kind, pairing_code.as_ref()),
|
||||
})
|
||||
.style(theme::Button::Secondary)
|
||||
.style(theme::button::secondary)
|
||||
.width(Length::Fill);
|
||||
if !processing && hw.is_supported() {
|
||||
bttn = bttn.on_press(Message::Select(i));
|
||||
@ -467,12 +467,12 @@ pub fn hardware_wallet_xpubs<'a>(
|
||||
col.push(
|
||||
Row::new()
|
||||
.spacing(5)
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.push(
|
||||
Container::new(
|
||||
scrollable(Container::new(text(xpub).small()).padding(10))
|
||||
.direction(scrollable::Direction::Horizontal(
|
||||
Properties::new().width(5).scroller_width(5),
|
||||
Scrollbar::new().width(5).scroller_width(5),
|
||||
)),
|
||||
)
|
||||
.width(Length::Fill),
|
||||
@ -489,7 +489,7 @@ pub fn hardware_wallet_xpubs<'a>(
|
||||
})
|
||||
})),
|
||||
)
|
||||
.style(theme::Container::Card(theme::Card::Simple))
|
||||
.style(theme::card::simple)
|
||||
.into()
|
||||
}
|
||||
|
||||
@ -510,7 +510,7 @@ pub fn share_xpubs<'a>(
|
||||
.width(Length::Fill),
|
||||
)
|
||||
.push_maybe(if hws.is_empty() {
|
||||
Some(p1_regular("No signing device connected").style(color::GREY_3))
|
||||
Some(p1_regular("No signing device connected").color(color::GREY_3))
|
||||
} else {
|
||||
None
|
||||
})
|
||||
@ -538,47 +538,22 @@ pub fn register_descriptor<'a>(
|
||||
done: bool,
|
||||
created_desc: bool,
|
||||
) -> Element<'a, Message> {
|
||||
let displayed_descriptor = if let Ok((template, keys)) =
|
||||
extract_keys_and_template::<String>(&descriptor)
|
||||
{
|
||||
let mut col = Column::new()
|
||||
.push(
|
||||
card::simple(
|
||||
Column::new()
|
||||
.push(text("Descriptor template:").small().bold())
|
||||
.push(
|
||||
scrollable(
|
||||
Column::new()
|
||||
.push(text(template).small())
|
||||
.push(Space::with_height(Length::Fixed(5.0))),
|
||||
)
|
||||
.direction(
|
||||
scrollable::Direction::Horizontal(
|
||||
scrollable::Properties::new().width(5).scroller_width(5),
|
||||
),
|
||||
),
|
||||
)
|
||||
.spacing(10),
|
||||
)
|
||||
.width(Length::Fill),
|
||||
)
|
||||
.push(Space::with_height(5));
|
||||
|
||||
for (index, key) in keys.into_iter().enumerate() {
|
||||
col = col
|
||||
let displayed_descriptor =
|
||||
if let Ok((template, keys)) = extract_keys_and_template::<String>(&descriptor) {
|
||||
let mut col = Column::new()
|
||||
.push(
|
||||
card::simple(
|
||||
Column::new()
|
||||
.push(text(format!("Key @{}:", index)).small().bold())
|
||||
.push(text("Descriptor template:").small().bold())
|
||||
.push(
|
||||
scrollable(
|
||||
Column::new()
|
||||
.push(text(key.to_owned()).small())
|
||||
.push(text(template).small())
|
||||
.push(Space::with_height(Length::Fixed(5.0))),
|
||||
)
|
||||
.direction(
|
||||
scrollable::Direction::Horizontal(
|
||||
scrollable::Properties::new().width(5).scroller_width(5),
|
||||
scrollable::Scrollbar::new().width(5).scroller_width(5),
|
||||
),
|
||||
),
|
||||
)
|
||||
@ -587,32 +562,56 @@ pub fn register_descriptor<'a>(
|
||||
.width(Length::Fill),
|
||||
)
|
||||
.push(Space::with_height(5));
|
||||
}
|
||||
|
||||
col
|
||||
} else {
|
||||
Column::new().push(card::simple(
|
||||
Column::new()
|
||||
.push(text("The descriptor:").small().bold())
|
||||
.push(
|
||||
scrollable(
|
||||
Column::new()
|
||||
.push(text(descriptor.to_owned()).small())
|
||||
.push(Space::with_height(Length::Fixed(5.0))),
|
||||
for (index, key) in keys.into_iter().enumerate() {
|
||||
col = col
|
||||
.push(
|
||||
card::simple(
|
||||
Column::new()
|
||||
.push(text(format!("Key @{}:", index)).small().bold())
|
||||
.push(
|
||||
scrollable(
|
||||
Column::new()
|
||||
.push(text(key.to_owned()).small())
|
||||
.push(Space::with_height(Length::Fixed(5.0))),
|
||||
)
|
||||
.direction(
|
||||
scrollable::Direction::Horizontal(
|
||||
scrollable::Scrollbar::new().width(5).scroller_width(5),
|
||||
),
|
||||
),
|
||||
)
|
||||
.spacing(10),
|
||||
)
|
||||
.width(Length::Fill),
|
||||
)
|
||||
.direction(scrollable::Direction::Horizontal(
|
||||
scrollable::Properties::new().width(5).scroller_width(5),
|
||||
)),
|
||||
)
|
||||
.push(
|
||||
Row::new().push(Column::new().width(Length::Fill)).push(
|
||||
button::secondary(Some(icon::clipboard_icon()), "Copy")
|
||||
.on_press(Message::Clibpboard(descriptor)),
|
||||
),
|
||||
)
|
||||
.spacing(10),
|
||||
))
|
||||
};
|
||||
.push(Space::with_height(5));
|
||||
}
|
||||
|
||||
col
|
||||
} else {
|
||||
Column::new().push(card::simple(
|
||||
Column::new()
|
||||
.push(text("The descriptor:").small().bold())
|
||||
.push(
|
||||
scrollable(
|
||||
Column::new()
|
||||
.push(text(descriptor.to_owned()).small())
|
||||
.push(Space::with_height(Length::Fixed(5.0))),
|
||||
)
|
||||
.direction(scrollable::Direction::Horizontal(
|
||||
scrollable::Scrollbar::new().width(5).scroller_width(5),
|
||||
)),
|
||||
)
|
||||
.push(
|
||||
Row::new().push(Column::new().width(Length::Fill)).push(
|
||||
button::secondary(Some(icon::clipboard_icon()), "Copy")
|
||||
.on_press(Message::Clibpboard(descriptor)),
|
||||
),
|
||||
)
|
||||
.spacing(10),
|
||||
))
|
||||
};
|
||||
layout(
|
||||
progress,
|
||||
email,
|
||||
@ -697,22 +696,22 @@ pub fn backup_descriptor<'a>(
|
||||
|| {
|
||||
Button::new(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.spacing(10)
|
||||
.push(text("Learn more").small().bold())
|
||||
.push(icon::collapse_icon()),
|
||||
)
|
||||
.style(theme::Button::Transparent)
|
||||
.style(theme::button::transparent)
|
||||
},
|
||||
|| {
|
||||
Button::new(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.spacing(10)
|
||||
.push(text("Learn more").small().bold())
|
||||
.push(icon::collapsed_icon()),
|
||||
)
|
||||
.style(theme::Button::Transparent)
|
||||
.style(theme::button::transparent)
|
||||
},
|
||||
help_backup,
|
||||
))
|
||||
@ -730,7 +729,7 @@ pub fn backup_descriptor<'a>(
|
||||
)
|
||||
.direction(
|
||||
scrollable::Direction::Horizontal(
|
||||
scrollable::Properties::new().width(5).scroller_width(5),
|
||||
scrollable::Scrollbar::new().width(5).scroller_width(5),
|
||||
),
|
||||
),
|
||||
)
|
||||
@ -803,7 +802,7 @@ fn display_policy(
|
||||
text(k.to_string()),
|
||||
iced_tooltip::Position::Bottom,
|
||||
)
|
||||
.style(theme::Container::Card(theme::Card::Simple)),
|
||||
.style(theme::card::simple),
|
||||
)
|
||||
} else {
|
||||
Container::new(text(format!("[{}]", k)).bold())
|
||||
@ -850,7 +849,7 @@ fn display_policy(
|
||||
text(k.to_string()),
|
||||
iced_tooltip::Position::Bottom,
|
||||
)
|
||||
.style(theme::Container::Card(theme::Card::Simple)),
|
||||
.style(theme::card::simple),
|
||||
)
|
||||
} else {
|
||||
Container::new(text(format!("[{}]", k)).bold())
|
||||
@ -880,7 +879,7 @@ fn display_policy(
|
||||
.spacing(10)
|
||||
.push(text("The wallet policy:").bold())
|
||||
.push(scrollable(col).direction(scrollable::Direction::Horizontal(
|
||||
scrollable::Properties::new().width(5).scroller_width(5),
|
||||
scrollable::Scrollbar::new().width(5).scroller_width(5),
|
||||
)))
|
||||
.into()
|
||||
}
|
||||
@ -957,7 +956,7 @@ pub fn define_bitcoin_node<'a>(
|
||||
},
|
||||
))
|
||||
.spacing(30)
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
},
|
||||
),
|
||||
)
|
||||
@ -966,7 +965,7 @@ pub fn define_bitcoin_node<'a>(
|
||||
Some(Container::new(
|
||||
Row::new()
|
||||
.spacing(10)
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.push(text("Checking connection...")),
|
||||
))
|
||||
} else if is_running.is_some() {
|
||||
@ -975,17 +974,17 @@ pub fn define_bitcoin_node<'a>(
|
||||
Container::new(
|
||||
Row::new()
|
||||
.spacing(10)
|
||||
.align_items(Alignment::Center)
|
||||
.push(icon::circle_check_icon().style(color::GREEN))
|
||||
.push(text("Connection checked").style(color::GREEN)),
|
||||
.align_y(Alignment::Center)
|
||||
.push(icon::circle_check_icon().color(color::GREEN))
|
||||
.push(text("Connection checked").color(color::GREEN)),
|
||||
)
|
||||
} else {
|
||||
Container::new(
|
||||
Row::new()
|
||||
.spacing(10)
|
||||
.align_items(Alignment::Center)
|
||||
.push(icon::circle_cross_icon().style(color::RED))
|
||||
.push(text("Connection failed").style(color::RED)),
|
||||
.align_y(Alignment::Center)
|
||||
.push(icon::circle_cross_icon().color(color::RED))
|
||||
.push(text("Connection failed").color(color::RED)),
|
||||
)
|
||||
}
|
||||
})
|
||||
@ -1059,7 +1058,7 @@ pub fn define_bitcoind<'a>(
|
||||
is not supported. Insert an IP address bound to the same machine \
|
||||
running Liana (ignore this warning if that's already the case)",
|
||||
)
|
||||
.style(color::ORANGE)
|
||||
.color(color::ORANGE)
|
||||
.size(text::CAPTION_SIZE),
|
||||
)
|
||||
} else {
|
||||
@ -1087,7 +1086,7 @@ pub fn define_bitcoind<'a>(
|
||||
},
|
||||
))
|
||||
.spacing(30)
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
},
|
||||
),
|
||||
)
|
||||
@ -1164,7 +1163,7 @@ pub fn select_bitcoind_type<'a>(progress: (usize, usize)) -> Element<'a, Message
|
||||
Column::new()
|
||||
.push(
|
||||
Row::new()
|
||||
.align_items(Alignment::Start)
|
||||
.align_y(Alignment::Start)
|
||||
.spacing(20)
|
||||
.push(
|
||||
Container::new(
|
||||
@ -1190,14 +1189,14 @@ pub fn select_bitcoind_type<'a>(progress: (usize, usize)) -> Element<'a, Message
|
||||
)
|
||||
.push(
|
||||
Row::new()
|
||||
.align_items(Alignment::Start)
|
||||
.align_y(Alignment::Start)
|
||||
.spacing(20)
|
||||
.push(
|
||||
Container::new(
|
||||
Column::new()
|
||||
.spacing(20)
|
||||
.width(Length::Fixed(300.0))
|
||||
.align_items(Alignment::Start)
|
||||
.align_x(Alignment::Start)
|
||||
.push(text(
|
||||
"Select this option if you already have \
|
||||
a Bitcoin node running locally or remotely. \
|
||||
@ -1211,7 +1210,7 @@ pub fn select_bitcoind_type<'a>(progress: (usize, usize)) -> Element<'a, Message
|
||||
Column::new()
|
||||
.spacing(20)
|
||||
.width(Length::Fixed(300.0))
|
||||
.align_items(Alignment::Start)
|
||||
.align_x(Alignment::Start)
|
||||
.push(text(
|
||||
"Liana will install a pruned node \
|
||||
on your computer. You won't need to do anything \
|
||||
@ -1227,14 +1226,14 @@ pub fn select_bitcoind_type<'a>(progress: (usize, usize)) -> Element<'a, Message
|
||||
)
|
||||
.push(
|
||||
Row::new()
|
||||
.align_items(Alignment::End)
|
||||
.align_y(Alignment::End)
|
||||
.spacing(20)
|
||||
.push(
|
||||
Container::new(
|
||||
Column::new()
|
||||
.spacing(20)
|
||||
.width(Length::Fixed(300.0))
|
||||
.align_items(Alignment::Center)
|
||||
.align_x(Alignment::Center)
|
||||
.push(
|
||||
button::secondary(None, "Select")
|
||||
.width(Length::Fixed(300.0))
|
||||
@ -1250,7 +1249,7 @@ pub fn select_bitcoind_type<'a>(progress: (usize, usize)) -> Element<'a, Message
|
||||
Column::new()
|
||||
.spacing(20)
|
||||
.width(Length::Fixed(300.0))
|
||||
.align_items(Alignment::Center)
|
||||
.align_x(Alignment::Center)
|
||||
.push(
|
||||
button::secondary(None, "Select")
|
||||
.width(Length::Fixed(300.0))
|
||||
@ -1285,53 +1284,53 @@ pub fn start_internal_bitcoind<'a>(
|
||||
match s {
|
||||
DownloadState::Finished(_) => Row::new()
|
||||
.spacing(10)
|
||||
.align_items(Alignment::Center)
|
||||
.push(icon::circle_check_icon().style(color::GREEN))
|
||||
.push(text("Download complete").style(color::GREEN)),
|
||||
.align_y(Alignment::Center)
|
||||
.push(icon::circle_check_icon().color(color::GREEN))
|
||||
.push(text("Download complete").color(color::GREEN)),
|
||||
DownloadState::Downloading { progress } => Row::new()
|
||||
.spacing(10)
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.push(text(format!(
|
||||
"Downloading Bitcoin Core {version}... {progress:.2}%"
|
||||
))),
|
||||
DownloadState::Errored(e) => Row::new()
|
||||
.spacing(10)
|
||||
.align_items(Alignment::Center)
|
||||
.push(icon::circle_cross_icon().style(color::RED))
|
||||
.push(text(format!("Download failed: '{}'.", e)).style(color::RED)),
|
||||
_ => Row::new().spacing(10).align_items(Alignment::Center),
|
||||
.align_y(Alignment::Center)
|
||||
.push(icon::circle_cross_icon().color(color::RED))
|
||||
.push(text(format!("Download failed: '{}'.", e)).color(color::RED)),
|
||||
_ => Row::new().spacing(10).align_y(Alignment::Center),
|
||||
}
|
||||
}))
|
||||
.push(Container::new(if let Some(state) = install_state {
|
||||
match state {
|
||||
InstallState::InProgress => Row::new()
|
||||
.spacing(10)
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.push("Installing bitcoind..."),
|
||||
InstallState::Finished => Row::new()
|
||||
.spacing(10)
|
||||
.align_items(Alignment::Center)
|
||||
.push(icon::circle_check_icon().style(color::GREEN))
|
||||
.push(text("Installation complete").style(color::GREEN)),
|
||||
.align_y(Alignment::Center)
|
||||
.push(icon::circle_check_icon().color(color::GREEN))
|
||||
.push(text("Installation complete").color(color::GREEN)),
|
||||
InstallState::Errored(e) => Row::new()
|
||||
.spacing(10)
|
||||
.align_items(Alignment::Center)
|
||||
.push(icon::circle_cross_icon().style(color::RED))
|
||||
.push(text(format!("Installation failed: '{}'.", e)).style(color::RED)),
|
||||
.align_y(Alignment::Center)
|
||||
.push(icon::circle_cross_icon().color(color::RED))
|
||||
.push(text(format!("Installation failed: '{}'.", e)).color(color::RED)),
|
||||
}
|
||||
} else if exe_path.is_some() {
|
||||
Row::new()
|
||||
.spacing(10)
|
||||
.align_items(Alignment::Center)
|
||||
.push(icon::circle_check_icon().style(color::GREEN))
|
||||
.push(text("Liana-managed bitcoind already installed").style(color::GREEN))
|
||||
.align_y(Alignment::Center)
|
||||
.push(icon::circle_check_icon().color(color::GREEN))
|
||||
.push(text("Liana-managed bitcoind already installed").color(color::GREEN))
|
||||
} else if let Some(DownloadState::Downloading { progress }) = download_state {
|
||||
Row::new()
|
||||
.spacing(10)
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.push(progress_bar(0.0..=100.0, *progress))
|
||||
} else {
|
||||
Row::new().spacing(10).align_items(Alignment::Center)
|
||||
Row::new().spacing(10).align_y(Alignment::Center)
|
||||
}))
|
||||
.push_maybe(if started.is_some() {
|
||||
started.map(|res| {
|
||||
@ -1339,18 +1338,18 @@ pub fn start_internal_bitcoind<'a>(
|
||||
Container::new(
|
||||
Row::new()
|
||||
.spacing(10)
|
||||
.align_items(Alignment::Center)
|
||||
.push(icon::circle_check_icon().style(color::GREEN))
|
||||
.push(text("Started").style(color::GREEN)),
|
||||
.align_y(Alignment::Center)
|
||||
.push(icon::circle_check_icon().color(color::GREEN))
|
||||
.push(text("Started").color(color::GREEN)),
|
||||
)
|
||||
} else {
|
||||
Container::new(
|
||||
Row::new()
|
||||
.spacing(10)
|
||||
.align_items(Alignment::Center)
|
||||
.push(icon::circle_cross_icon().style(color::RED))
|
||||
.align_y(Alignment::Center)
|
||||
.push(icon::circle_cross_icon().color(color::RED))
|
||||
.push(
|
||||
text(res.as_ref().err().unwrap().to_string()).style(color::RED),
|
||||
text(res.as_ref().err().unwrap().to_string()).color(color::RED),
|
||||
),
|
||||
)
|
||||
}
|
||||
@ -1361,7 +1360,7 @@ pub fn start_internal_bitcoind<'a>(
|
||||
(Some(InstallState::Finished), _) | (None, Some(_)) => Some(Container::new(
|
||||
Row::new()
|
||||
.spacing(10)
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.push(text("Starting...")),
|
||||
)),
|
||||
_ => Some(Container::new(Space::with_height(Length::Fixed(25.0)))),
|
||||
@ -1411,9 +1410,9 @@ pub fn install<'a>(
|
||||
Container::new(
|
||||
Row::new()
|
||||
.spacing(10)
|
||||
.align_items(Alignment::Center)
|
||||
.push(icon::circle_check_icon().style(color::GREEN))
|
||||
.push(text("Installed").style(color::GREEN)),
|
||||
.align_y(Alignment::Center)
|
||||
.push(icon::circle_check_icon().color(color::GREEN))
|
||||
.push(text("Installed").color(color::GREEN)),
|
||||
)
|
||||
} else {
|
||||
Container::new(Space::with_height(Length::Fixed(25.0)))
|
||||
@ -1436,7 +1435,7 @@ pub fn defined_threshold<'a>(
|
||||
.spacing(10)
|
||||
.push((0..threshold.1).fold(Row::new(), |row, i| {
|
||||
if i < threshold.0 {
|
||||
row.push(icon::round_key_icon().style(color))
|
||||
row.push(icon::round_key_icon().color(color))
|
||||
} else {
|
||||
row.push(icon::round_key_icon())
|
||||
}
|
||||
@ -1451,7 +1450,7 @@ pub fn defined_threshold<'a>(
|
||||
)
|
||||
.padding(10)
|
||||
.on_press(message::DefinePath::EditThreshold)
|
||||
.style(theme::Button::Secondary)
|
||||
.style(theme::button::secondary)
|
||||
.into()
|
||||
} else {
|
||||
card::simple(
|
||||
@ -1459,7 +1458,7 @@ pub fn defined_threshold<'a>(
|
||||
.spacing(10)
|
||||
.push((0..threshold.1).fold(Row::new(), |row, i| {
|
||||
if i < threshold.0 {
|
||||
row.push(icon::round_key_icon().style(color))
|
||||
row.push(icon::round_key_icon().color(color))
|
||||
} else {
|
||||
row.push(icon::round_key_icon())
|
||||
}
|
||||
@ -1485,21 +1484,21 @@ pub fn defined_sequence<'a>(
|
||||
Column::new()
|
||||
.spacing(5)
|
||||
.push(if sequence != 0 {
|
||||
Row::new().align_items(Alignment::Center).push(
|
||||
Row::new().align_y(Alignment::Center).push(
|
||||
Container::new(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.spacing(5)
|
||||
.push(
|
||||
text::p1_regular("Available after inactivity of ~")
|
||||
.style(color::GREY_2),
|
||||
.color(color::GREY_2),
|
||||
)
|
||||
.push(
|
||||
Button::new(
|
||||
Row::new()
|
||||
.padding(5)
|
||||
.spacing(5)
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.push(text(
|
||||
[
|
||||
(n_years, "y"),
|
||||
@ -1521,7 +1520,7 @@ pub fn defined_sequence<'a>(
|
||||
))
|
||||
.push(icon::pencil_icon()),
|
||||
)
|
||||
.style(theme::Button::Secondary)
|
||||
.style(theme::button::secondary)
|
||||
.on_press(message::DefinePath::EditSequence),
|
||||
),
|
||||
)
|
||||
@ -1531,14 +1530,14 @@ pub fn defined_sequence<'a>(
|
||||
)
|
||||
} else {
|
||||
Row::new()
|
||||
.push(p1_regular("Able to move the funds at any time.").style(color::GREY_2))
|
||||
.push(p1_regular("Able to move the funds at any time.").color(color::GREY_2))
|
||||
.padding(5)
|
||||
})
|
||||
.push_maybe(if duplicate_sequence {
|
||||
Some(
|
||||
text("No two recovery options may become available at the very same date.")
|
||||
.small()
|
||||
.style(color::RED),
|
||||
.color(color::RED),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
@ -1614,14 +1613,14 @@ pub fn hw_list_view(
|
||||
kind, pairing_code, ..
|
||||
} => hw::locked_hardware_wallet(kind, pairing_code.as_ref()),
|
||||
})
|
||||
.style(theme::Button::Border)
|
||||
.style(theme::button::container_border)
|
||||
.width(Length::Fill);
|
||||
if !processing && hw.is_supported() {
|
||||
bttn = bttn.on_press(Message::Select(i));
|
||||
}
|
||||
Container::new(bttn)
|
||||
.width(Length::Fill)
|
||||
.style(theme::Container::Card(theme::Card::Simple))
|
||||
.style(theme::card::simple)
|
||||
.into()
|
||||
}
|
||||
|
||||
@ -1666,14 +1665,14 @@ pub fn key_list_view<'a>(
|
||||
Some(name),
|
||||
)
|
||||
})
|
||||
.style(theme::Button::Border)
|
||||
.style(theme::button::secondary)
|
||||
.width(Length::Fill)
|
||||
.on_press(Message::DefineDescriptor(
|
||||
message::DefineDescriptor::KeyModal(message::ImportKeyModal::SelectKey(i)),
|
||||
));
|
||||
Container::new(bttn)
|
||||
.width(Length::Fill)
|
||||
.style(theme::Container::Card(theme::Card::Simple))
|
||||
.style(theme::card::simple)
|
||||
.into()
|
||||
}
|
||||
|
||||
@ -1696,7 +1695,7 @@ pub fn backup_mnemonic<'a>(
|
||||
.fold(Column::new().spacing(5), |acc, (i, w)| {
|
||||
acc.push(
|
||||
Row::new()
|
||||
.align_items(Alignment::End)
|
||||
.align_y(Alignment::End)
|
||||
.push(
|
||||
Container::new(text(format!("#{}", i + 1)).small())
|
||||
.width(Length::Fixed(50.0)),
|
||||
@ -1738,13 +1737,13 @@ pub fn recover_mnemonic<'a>(
|
||||
.push_maybe(if recover {
|
||||
Some(
|
||||
Column::new()
|
||||
.align_items(Alignment::Center)
|
||||
.align_x(Alignment::Center)
|
||||
.push(
|
||||
Container::new(if !suggestions.is_empty() {
|
||||
suggestions.iter().fold(Row::new().spacing(5), |row, sugg| {
|
||||
row.push(
|
||||
Button::new(text(sugg))
|
||||
.style(theme::Button::Secondary)
|
||||
.style(theme::button::secondary)
|
||||
.on_press(Message::MnemonicWord(
|
||||
current,
|
||||
sugg.to_string(),
|
||||
@ -1763,7 +1762,7 @@ pub fn recover_mnemonic<'a>(
|
||||
acc.push(
|
||||
Row::new()
|
||||
.spacing(10)
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.push(
|
||||
Container::new(text(format!("#{}", i + 1)).small())
|
||||
.width(Length::Fixed(50.0)),
|
||||
@ -1775,7 +1774,7 @@ pub fn recover_mnemonic<'a>(
|
||||
.width(Length::Fixed(100.0)),
|
||||
)
|
||||
.push_maybe(if *valid {
|
||||
Some(icon::circle_check_icon().style(color::GREEN))
|
||||
Some(icon::circle_check_icon().color(color::GREEN))
|
||||
} else {
|
||||
None
|
||||
}),
|
||||
@ -1783,7 +1782,7 @@ pub fn recover_mnemonic<'a>(
|
||||
},
|
||||
))
|
||||
.push(Space::with_height(Length::Fixed(50.0)))
|
||||
.push_maybe(error.map(|e| card::invalid(text(e).style(color::RED)))),
|
||||
.push_maybe(error.map(|e| card::invalid(text(e).color(color::RED)))),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
@ -1839,14 +1838,14 @@ pub fn choose_backend(progress: (usize, usize)) -> Element<'static, Message> {
|
||||
.spacing(20)
|
||||
.width(Length::FillPortion(1))
|
||||
.push(h3("Use your own node"))
|
||||
.push(text::p2_medium(LOCAL_WALLET_DESC).style(color::GREY_3)),
|
||||
.push(text::p2_medium(LOCAL_WALLET_DESC).color(color::GREY_3)),
|
||||
)
|
||||
.push(
|
||||
Column::new()
|
||||
.spacing(20)
|
||||
.width(Length::FillPortion(1))
|
||||
.push(h3("Use Liana Connect"))
|
||||
.push(text::p2_medium(REMOTE_BACKEND_DESC).style(color::GREY_3)),
|
||||
.push(text::p2_medium(REMOTE_BACKEND_DESC).color(color::GREY_3)),
|
||||
),
|
||||
)
|
||||
.push(
|
||||
@ -1888,13 +1887,12 @@ pub fn login(progress: (usize, usize), connection_step: Element<Message>) -> Ele
|
||||
Column::new()
|
||||
.spacing(50)
|
||||
.max_width(700)
|
||||
.align_items(Alignment::Center)
|
||||
.align_x(Alignment::Center)
|
||||
.width(Length::FillPortion(1))
|
||||
.push(h2("Liana Connect"))
|
||||
.push(connection_step),
|
||||
)
|
||||
.width(Length::Fill)
|
||||
.center_x(),
|
||||
.center_x(Length::Fill),
|
||||
true,
|
||||
Some(Message::Previous),
|
||||
)
|
||||
@ -1908,8 +1906,8 @@ pub fn connection_step_enter_email<'a>(
|
||||
) -> Element<'a, Message> {
|
||||
Column::new()
|
||||
.spacing(20)
|
||||
.push_maybe(connection_error.map(|e| text(e.to_string()).style(color::ORANGE)))
|
||||
.push_maybe(auth_error.map(|e| text(e.to_string()).style(color::ORANGE)))
|
||||
.push_maybe(connection_error.map(|e| text(e.to_string()).color(color::ORANGE)))
|
||||
.push_maybe(auth_error.map(|e| text(e.to_string()).color(color::ORANGE)))
|
||||
.push(text(
|
||||
"Enter the email you want to associate with the wallet:",
|
||||
))
|
||||
@ -1942,10 +1940,10 @@ pub fn connection_step_enter_otp<'a>(
|
||||
) -> Element<'a, Message> {
|
||||
Column::new()
|
||||
.spacing(20)
|
||||
.push(text(email).style(color::GREEN))
|
||||
.push(text(email).color(color::GREEN))
|
||||
.push(text("An authentication token has been emailed to you"))
|
||||
.push_maybe(connection_error.map(|e| text(e.to_string()).style(color::ORANGE)))
|
||||
.push_maybe(auth_error.map(|e| text(e.to_string()).style(color::ORANGE)))
|
||||
.push_maybe(connection_error.map(|e| text(e.to_string()).color(color::ORANGE)))
|
||||
.push_maybe(auth_error.map(|e| text(e.to_string()).color(color::ORANGE)))
|
||||
.push(
|
||||
form::Form::new_trimmed("Token", otp, |msg| {
|
||||
Message::SelectBackend(message::SelectBackend::OTPEdited(msg))
|
||||
@ -1980,9 +1978,9 @@ pub fn connection_step_connected<'a>(
|
||||
) -> Element<'a, Message> {
|
||||
Column::new()
|
||||
.spacing(20)
|
||||
.push(text(email).style(color::GREEN))
|
||||
.push_maybe(connection_error.map(|e| text(e.to_string()).style(color::ORANGE)))
|
||||
.push_maybe(auth_error.map(|e| text(e.to_string()).style(color::ORANGE)))
|
||||
.push(text(email).color(color::GREEN))
|
||||
.push_maybe(connection_error.map(|e| text(e.to_string()).color(color::ORANGE)))
|
||||
.push_maybe(auth_error.map(|e| text(e.to_string()).color(color::ORANGE)))
|
||||
.push(Container::new(
|
||||
Row::new()
|
||||
.spacing(10)
|
||||
@ -2021,23 +2019,18 @@ fn layout<'a>(
|
||||
Column::new()
|
||||
.width(Length::Fill)
|
||||
.push(Row::new().push(Space::with_width(Length::Fill)).push_maybe(
|
||||
email.map(|e| Container::new(p1_regular(e).style(color::GREEN)).padding(20)),
|
||||
email.map(|e| Container::new(p1_regular(e).color(color::GREEN)).padding(20)),
|
||||
))
|
||||
.push(Space::with_height(Length::Fixed(100.0)))
|
||||
.push(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.push(
|
||||
Container::new(prev_button)
|
||||
.width(Length::FillPortion(2))
|
||||
.center_x(),
|
||||
)
|
||||
.align_y(Alignment::Center)
|
||||
.push(Container::new(prev_button).center_x(Length::FillPortion(2)))
|
||||
.push(Container::new(h3(title)).width(Length::FillPortion(8)))
|
||||
.push_maybe(if progress.1 > 0 {
|
||||
Some(
|
||||
Container::new(text(format!("{} | {}", progress.0, progress.1)))
|
||||
.width(Length::FillPortion(2))
|
||||
.center_x(),
|
||||
.center_x(Length::FillPortion(2)),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
@ -2065,9 +2058,9 @@ fn layout<'a>(
|
||||
}),
|
||||
),
|
||||
))
|
||||
.center_x()
|
||||
.center_x(Length::Fill)
|
||||
.height(Length::Fill)
|
||||
.width(Length::Fill)
|
||||
.style(theme::Container::Background)
|
||||
.style(theme::container::background)
|
||||
.into()
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@ use std::path::PathBuf;
|
||||
use iced::{
|
||||
alignment::Horizontal,
|
||||
widget::{pick_list, scrollable, Button, Space},
|
||||
Alignment, Command, Length, Subscription,
|
||||
Alignment, Length, Subscription, Task,
|
||||
};
|
||||
|
||||
use liana::miniscript::bitcoin::Network;
|
||||
@ -44,7 +44,7 @@ pub struct Launcher {
|
||||
}
|
||||
|
||||
impl Launcher {
|
||||
pub fn new(datadir_path: PathBuf, network: Option<Network>) -> (Self, Command<Message>) {
|
||||
pub fn new(datadir_path: PathBuf, network: Option<Network>) -> (Self, Task<Message>) {
|
||||
let network = network.unwrap_or(
|
||||
NETWORKS
|
||||
.iter()
|
||||
@ -60,7 +60,7 @@ impl Launcher {
|
||||
error: None,
|
||||
delete_wallet_modal: None,
|
||||
},
|
||||
Command::perform(
|
||||
Task::perform(
|
||||
check_network_datadir(datadir_path.clone(), network),
|
||||
Message::Checked,
|
||||
),
|
||||
@ -73,26 +73,26 @@ impl Launcher {
|
||||
Subscription::none()
|
||||
}
|
||||
|
||||
pub fn update(&mut self, message: Message) -> Command<Message> {
|
||||
pub fn update(&mut self, message: Message) -> Task<Message> {
|
||||
match message {
|
||||
Message::View(ViewMessage::ImportWallet) => {
|
||||
let datadir_path = self.datadir_path.clone();
|
||||
let network = self.network;
|
||||
Command::perform(async move { (datadir_path, network) }, |(d, n)| {
|
||||
Task::perform(async move { (datadir_path, network) }, |(d, n)| {
|
||||
Message::Install(d, n, UserFlow::AddWallet)
|
||||
})
|
||||
}
|
||||
Message::View(ViewMessage::CreateWallet) => {
|
||||
let datadir_path = self.datadir_path.clone();
|
||||
let network = self.network;
|
||||
Command::perform(async move { (datadir_path, network) }, |(d, n)| {
|
||||
Task::perform(async move { (datadir_path, network) }, |(d, n)| {
|
||||
Message::Install(d, n, UserFlow::CreateWallet)
|
||||
})
|
||||
}
|
||||
Message::View(ViewMessage::ShareXpubs) => {
|
||||
let datadir_path = self.datadir_path.clone();
|
||||
let network = self.network;
|
||||
Command::perform(async move { (datadir_path, network) }, |(d, n)| {
|
||||
Task::perform(async move { (datadir_path, network) }, |(d, n)| {
|
||||
Message::Install(d, n, UserFlow::ShareXpubs)
|
||||
})
|
||||
}
|
||||
@ -109,31 +109,31 @@ impl Launcher {
|
||||
wallet_datadir,
|
||||
internal_bitcoind,
|
||||
));
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
Message::View(ViewMessage::SelectNetwork(network)) => {
|
||||
self.network = network;
|
||||
Command::perform(
|
||||
Task::perform(
|
||||
check_network_datadir(self.datadir_path.clone(), self.network),
|
||||
Message::Checked,
|
||||
)
|
||||
}
|
||||
Message::View(ViewMessage::DeleteWallet(DeleteWalletMessage::Deleted)) => {
|
||||
self.state = State::NoWallet;
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
Message::View(ViewMessage::DeleteWallet(DeleteWalletMessage::CloseModal)) => {
|
||||
self.delete_wallet_modal = None;
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
Message::Checked(res) => match res {
|
||||
Err(e) => {
|
||||
self.error = Some(e);
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
Ok(state) => {
|
||||
self.state = state;
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
},
|
||||
Message::View(ViewMessage::Run) => {
|
||||
@ -144,18 +144,18 @@ impl Launcher {
|
||||
path.push(app::config::DEFAULT_FILE_NAME);
|
||||
let cfg = app::Config::from_file(&path).expect("Already checked");
|
||||
let network = self.network;
|
||||
Command::perform(async move { (datadir_path.clone(), cfg, network) }, |m| {
|
||||
Task::perform(async move { (datadir_path.clone(), cfg, network) }, |m| {
|
||||
Message::Run(m.0, m.1, m.2)
|
||||
})
|
||||
} else {
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
if let Some(modal) = &mut self.delete_wallet_modal {
|
||||
return modal.update(message);
|
||||
}
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -180,16 +180,16 @@ impl Launcher {
|
||||
Some(self.network),
|
||||
ViewMessage::SelectNetwork,
|
||||
)
|
||||
.style(theme::PickList::default())
|
||||
.style(theme::pick_list::primary)
|
||||
.padding(10),
|
||||
)
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.padding(100),
|
||||
)
|
||||
.push(
|
||||
Container::new(
|
||||
Column::new()
|
||||
.align_items(Alignment::Center)
|
||||
.align_x(Alignment::Center)
|
||||
.spacing(30)
|
||||
.push(if matches!(self.state, State::Wallet { .. }) {
|
||||
text("Welcome back").size(50).bold()
|
||||
@ -203,7 +203,7 @@ impl Launcher {
|
||||
email, checksum, ..
|
||||
} => Column::new().push(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.spacing(20)
|
||||
.push(
|
||||
Button::new(
|
||||
@ -220,25 +220,25 @@ impl Launcher {
|
||||
)))
|
||||
.push_maybe(checksum.as_ref().map(|checksum| {
|
||||
p1_regular(format!("Liana-{}", checksum))
|
||||
.style(color::GREY_3)
|
||||
.color(color::GREY_3)
|
||||
}))
|
||||
.push_maybe(email.as_ref().map(|email| {
|
||||
Row::new()
|
||||
.push(Space::with_width(Length::Fill))
|
||||
.push(
|
||||
p1_regular(email)
|
||||
.style(color::GREEN),
|
||||
.color(color::GREEN),
|
||||
)
|
||||
})),
|
||||
)
|
||||
.on_press(ViewMessage::Run)
|
||||
.style(theme::Button::Border)
|
||||
.style(theme::button::container_border)
|
||||
.padding(10)
|
||||
.width(Length::Fill),
|
||||
)
|
||||
.push(
|
||||
Button::new(icon::trash_icon())
|
||||
.style(theme::Button::Secondary)
|
||||
.style(theme::button::secondary)
|
||||
.padding(10)
|
||||
.on_press(ViewMessage::DeleteWallet(
|
||||
DeleteWalletMessage::ShowModal,
|
||||
@ -248,20 +248,20 @@ impl Launcher {
|
||||
State::NoWallet => Column::new()
|
||||
.push(
|
||||
Row::new()
|
||||
.align_items(Alignment::End)
|
||||
.align_y(Alignment::End)
|
||||
.spacing(20)
|
||||
.push(
|
||||
Container::new(
|
||||
Column::new()
|
||||
.spacing(20)
|
||||
.align_items(Alignment::Center)
|
||||
.align_x(Alignment::Center)
|
||||
.push(
|
||||
image::create_new_wallet_icon()
|
||||
.width(Length::Fixed(100.0)),
|
||||
)
|
||||
.push(
|
||||
p1_regular("Create a new Liana wallet")
|
||||
.style(color::GREY_3),
|
||||
.color(color::GREY_3),
|
||||
)
|
||||
.push(
|
||||
button::secondary(None, "Select")
|
||||
@ -270,7 +270,7 @@ impl Launcher {
|
||||
ViewMessage::CreateWallet,
|
||||
),
|
||||
)
|
||||
.align_items(Alignment::Center),
|
||||
.align_x(Alignment::Center),
|
||||
)
|
||||
.padding(20),
|
||||
)
|
||||
@ -278,7 +278,7 @@ impl Launcher {
|
||||
Container::new(
|
||||
Column::new()
|
||||
.spacing(20)
|
||||
.align_items(Alignment::Center)
|
||||
.align_x(Alignment::Center)
|
||||
.push(
|
||||
image::restore_wallet_icon()
|
||||
.width(Length::Fixed(100.0)),
|
||||
@ -287,7 +287,7 @@ impl Launcher {
|
||||
p1_regular(
|
||||
"Add an existing Liana wallet",
|
||||
)
|
||||
.style(color::GREY_3),
|
||||
.color(color::GREY_3),
|
||||
)
|
||||
.push(
|
||||
button::secondary(None, "Select")
|
||||
@ -296,17 +296,16 @@ impl Launcher {
|
||||
ViewMessage::ImportWallet,
|
||||
),
|
||||
)
|
||||
.align_items(Alignment::Center),
|
||||
.align_x(Alignment::Center),
|
||||
)
|
||||
.padding(20),
|
||||
),
|
||||
)
|
||||
.align_items(Alignment::Center),
|
||||
.align_x(Alignment::Center),
|
||||
})
|
||||
.max_width(500),
|
||||
)
|
||||
.width(Length::Fill)
|
||||
.center_x(),
|
||||
.center_x(Length::Fill),
|
||||
)
|
||||
.push(Space::with_height(Length::Fixed(100.0))),
|
||||
))
|
||||
@ -376,24 +375,24 @@ impl DeleteWalletModal {
|
||||
}
|
||||
}
|
||||
|
||||
fn update(&mut self, message: Message) -> Command<Message> {
|
||||
fn update(&mut self, message: Message) -> Task<Message> {
|
||||
if let Message::View(ViewMessage::DeleteWallet(DeleteWalletMessage::Confirm)) = message {
|
||||
self.warning = None;
|
||||
if let Err(e) = std::fs::remove_dir_all(&self.wallet_datadir) {
|
||||
self.warning = Some(e);
|
||||
} else {
|
||||
self.deleted = true;
|
||||
return Command::perform(async {}, |_| {
|
||||
return Task::perform(async {}, |_| {
|
||||
Message::View(ViewMessage::DeleteWallet(DeleteWalletMessage::Deleted))
|
||||
});
|
||||
};
|
||||
}
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
fn view(&self) -> Element<Message> {
|
||||
let mut confirm_button = button::secondary(None, "Delete wallet")
|
||||
.width(Length::Fixed(200.0))
|
||||
.style(theme::Button::Destructive);
|
||||
.style(theme::button::destructive);
|
||||
if self.warning.is_none() {
|
||||
confirm_button =
|
||||
confirm_button.on_press(ViewMessage::DeleteWallet(DeleteWalletMessage::Confirm));
|
||||
@ -416,12 +415,12 @@ impl DeleteWalletModal {
|
||||
.spacing(10)
|
||||
.push(Container::new(
|
||||
h4_bold(format!("Delete configuration for {}", &self.network))
|
||||
.style(color::RED)
|
||||
.color(color::RED)
|
||||
.width(Length::Fill),
|
||||
))
|
||||
.push(Row::new().push(text(help_text_1)))
|
||||
.push_maybe(
|
||||
help_text_2.map(|t| Row::new().push(p1_regular(t).style(color::GREY_3))),
|
||||
help_text_2.map(|t| Row::new().push(p1_regular(t).color(color::GREY_3))),
|
||||
)
|
||||
.push(Row::new())
|
||||
.push(Row::new().push(text(help_text_3)))
|
||||
@ -434,8 +433,8 @@ impl DeleteWalletModal {
|
||||
} else {
|
||||
Row::new()
|
||||
.spacing(10)
|
||||
.push(icon::circle_check_icon().style(color::GREEN))
|
||||
.push(text("Wallet successfully deleted").style(color::GREEN))
|
||||
.push(icon::circle_check_icon().color(color::GREEN))
|
||||
.push(text("Wallet successfully deleted").color(color::GREEN))
|
||||
})
|
||||
.align_x(Horizontal::Center)
|
||||
.width(Length::Fill),
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
use std::{path::PathBuf, sync::Arc};
|
||||
|
||||
use iced::{Alignment, Command, Length};
|
||||
use iced::{Alignment, Length, Task};
|
||||
|
||||
use liana::miniscript::bitcoin::Network;
|
||||
use liana_ui::{
|
||||
@ -116,7 +116,7 @@ pub enum ConnectionStep {
|
||||
}
|
||||
|
||||
impl LianaLiteLogin {
|
||||
pub fn new(datadir: PathBuf, network: Network, settings: Settings) -> (Self, Command<Message>) {
|
||||
pub fn new(datadir: PathBuf, network: Network, settings: Settings) -> (Self, Task<Message>) {
|
||||
match settings
|
||||
.wallets
|
||||
.first()
|
||||
@ -137,7 +137,7 @@ impl LianaLiteLogin {
|
||||
auth_error: None,
|
||||
processing: true,
|
||||
},
|
||||
Command::none(),
|
||||
Task::none(),
|
||||
),
|
||||
Ok(auth_config) => (
|
||||
Self {
|
||||
@ -149,7 +149,7 @@ impl LianaLiteLogin {
|
||||
auth_error: None,
|
||||
processing: true,
|
||||
},
|
||||
Command::perform(
|
||||
Task::perform(
|
||||
async move {
|
||||
let service_config = super::client::get_service_config(network)
|
||||
.await
|
||||
@ -174,7 +174,7 @@ impl LianaLiteLogin {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update(&mut self, message: Message) -> Command<Message> {
|
||||
pub fn update(&mut self, message: Message) -> Task<Message> {
|
||||
match &mut self.step {
|
||||
ConnectionStep::CheckingAuthFile => {
|
||||
if let Message::Connected(res) = message {
|
||||
@ -184,7 +184,7 @@ impl LianaLiteLogin {
|
||||
self.auth_error = Some("No wallet found for the given email");
|
||||
}
|
||||
Ok(BackendState::WalletExists(client, wallet)) => {
|
||||
return Command::perform(async move { (client, wallet) }, |(c, w)| {
|
||||
return Task::perform(async move { (client, wallet) }, |(c, w)| {
|
||||
Message::Run(Ok((c, w)))
|
||||
});
|
||||
}
|
||||
@ -216,7 +216,7 @@ impl LianaLiteLogin {
|
||||
self.processing = true;
|
||||
self.connection_error = None;
|
||||
self.auth_error = None;
|
||||
return Command::perform(
|
||||
return Task::perform(
|
||||
async move {
|
||||
let config = super::client::get_service_config(network)
|
||||
.await
|
||||
@ -279,7 +279,7 @@ impl LianaLiteLogin {
|
||||
self.processing = true;
|
||||
self.connection_error = None;
|
||||
self.auth_error = None;
|
||||
return Command::perform(
|
||||
return Task::perform(
|
||||
async move {
|
||||
client.resend_otp().await?;
|
||||
Ok(())
|
||||
@ -309,7 +309,7 @@ impl LianaLiteLogin {
|
||||
self.auth_error = None;
|
||||
let wallet_id = self.wallet_id.clone();
|
||||
let network = self.network;
|
||||
return Command::perform(
|
||||
return Task::perform(
|
||||
async move {
|
||||
connect(client, otp, wallet_id, backend_api_url, network).await
|
||||
},
|
||||
@ -322,12 +322,12 @@ impl LianaLiteLogin {
|
||||
self.processing = false;
|
||||
match res {
|
||||
Ok(BackendState::NoWallet(client)) => {
|
||||
return Command::perform(async move { Some(client) }, Message::Install);
|
||||
return Task::perform(async move { Some(client) }, Message::Install);
|
||||
}
|
||||
Ok(BackendState::WalletExists(client, wallet)) => {
|
||||
let datadir = self.datadir.clone();
|
||||
let network = self.network;
|
||||
return Command::perform(
|
||||
return Task::perform(
|
||||
async move {
|
||||
update_wallet_auth_settings(
|
||||
datadir,
|
||||
@ -366,7 +366,7 @@ impl LianaLiteLogin {
|
||||
},
|
||||
}
|
||||
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
|
||||
pub fn view(&self) -> Element<Message> {
|
||||
@ -374,10 +374,10 @@ impl LianaLiteLogin {
|
||||
Container::new(
|
||||
Column::new()
|
||||
.spacing(100)
|
||||
.align_items(Alignment::Center)
|
||||
.align_x(Alignment::Center)
|
||||
.push(
|
||||
Column::new()
|
||||
.align_items(Alignment::Center)
|
||||
.align_x(Alignment::Center)
|
||||
.spacing(20)
|
||||
.width(Length::Fill)
|
||||
.push(h2("Liana Connect"))
|
||||
@ -391,7 +391,7 @@ impl LianaLiteLogin {
|
||||
.spacing(20)
|
||||
.push_maybe(
|
||||
self.auth_error
|
||||
.map(|e| text(e).style(color::ORANGE)),
|
||||
.map(|e| text(e).color(color::ORANGE)),
|
||||
)
|
||||
.push(
|
||||
form::Form::new_trimmed("email", email, |msg| {
|
||||
@ -412,7 +412,7 @@ impl LianaLiteLogin {
|
||||
.push(text("An authentication was send to your email"))
|
||||
.push_maybe(
|
||||
self.auth_error
|
||||
.map(|e| text(e).style(color::ORANGE)),
|
||||
.map(|e| text(e).color(color::ORANGE)),
|
||||
)
|
||||
.spacing(20)
|
||||
.push(
|
||||
@ -456,10 +456,8 @@ impl LianaLiteLogin {
|
||||
}),
|
||||
)
|
||||
.padding(50)
|
||||
.width(Length::Fill)
|
||||
.height(Length::Fill)
|
||||
.center_x()
|
||||
.center_y(),
|
||||
.center_x(Length::Fill)
|
||||
.center_y(Length::Fill),
|
||||
)
|
||||
.map(Message::View);
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@ use std::path::{Path, PathBuf};
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
||||
use iced::{Alignment, Command, Length, Subscription};
|
||||
use iced::{Alignment, Length, Subscription, Task};
|
||||
use tokio::runtime::Handle;
|
||||
use tracing::{debug, info, warn};
|
||||
|
||||
@ -99,7 +99,7 @@ impl Loader {
|
||||
gui_config: GUIConfig,
|
||||
network: bitcoin::Network,
|
||||
internal_bitcoind: Option<Bitcoind>,
|
||||
) -> (Self, Command<Message>) {
|
||||
) -> (Self, Task<Message>) {
|
||||
let path = gui_config
|
||||
.daemon_rpc_path
|
||||
.clone()
|
||||
@ -114,7 +114,7 @@ impl Loader {
|
||||
internal_bitcoind,
|
||||
waiting_daemon_bitcoind: false,
|
||||
},
|
||||
Command::perform(connect(path), Message::Loaded),
|
||||
Task::perform(connect(path), Message::Loaded),
|
||||
)
|
||||
}
|
||||
|
||||
@ -122,11 +122,11 @@ impl Loader {
|
||||
&mut self,
|
||||
daemon: Arc<dyn Daemon + Sync + Send>,
|
||||
info: GetInfoResult,
|
||||
) -> Command<Message> {
|
||||
) -> Task<Message> {
|
||||
// If the wallet was previously synced (blockheight > 0), load the
|
||||
// application directly.
|
||||
if info.block_height > 0 {
|
||||
return Command::perform(
|
||||
return Task::perform(
|
||||
load_application(
|
||||
daemon,
|
||||
info,
|
||||
@ -143,13 +143,13 @@ impl Loader {
|
||||
progress: 0.0,
|
||||
bitcoind_logs: String::new(),
|
||||
};
|
||||
Command::perform(sync(daemon, false), Message::Syncing)
|
||||
Task::perform(sync(daemon, false), Message::Syncing)
|
||||
}
|
||||
|
||||
fn on_load(
|
||||
&mut self,
|
||||
res: Result<(Arc<dyn Daemon + Sync + Send>, GetInfoResult), Error>,
|
||||
) -> Command<Message> {
|
||||
) -> Task<Message> {
|
||||
match res {
|
||||
Ok((daemon, info)) => {
|
||||
if self.gui_config.start_internal_bitcoind {
|
||||
@ -168,7 +168,7 @@ impl Loader {
|
||||
self.step = Step::StartingDaemon;
|
||||
self.daemon_started = true;
|
||||
self.waiting_daemon_bitcoind = true;
|
||||
return Command::perform(
|
||||
return Task::perform(
|
||||
start_bitcoind_and_daemon(
|
||||
daemon_config_path,
|
||||
self.datadir_path.clone(),
|
||||
@ -186,19 +186,19 @@ impl Loader {
|
||||
}
|
||||
},
|
||||
}
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
|
||||
fn on_log(&mut self, log: Option<String>) -> Command<Message> {
|
||||
fn on_log(&mut self, log: Option<String>) -> Task<Message> {
|
||||
if let Step::Syncing { bitcoind_logs, .. } = &mut self.step {
|
||||
if let Some(l) = log {
|
||||
*bitcoind_logs = l;
|
||||
}
|
||||
}
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
|
||||
fn on_start(&mut self, res: StartedResult) -> Command<Message> {
|
||||
fn on_start(&mut self, res: StartedResult) -> Task<Message> {
|
||||
match res {
|
||||
Ok((daemon, bitcoind, info)) => {
|
||||
// bitcoind may have been already started and given to the loader
|
||||
@ -211,12 +211,12 @@ impl Loader {
|
||||
}
|
||||
Err(e) => {
|
||||
self.step = Step::Error(Box::new(e));
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn on_sync(&mut self, res: Result<GetInfoResult, DaemonError>) -> Command<Message> {
|
||||
fn on_sync(&mut self, res: Result<GetInfoResult, DaemonError>) -> Task<Message> {
|
||||
match &mut self.step {
|
||||
Step::Syncing {
|
||||
daemon, progress, ..
|
||||
@ -224,7 +224,7 @@ impl Loader {
|
||||
match res {
|
||||
Ok(info) => {
|
||||
if (info.sync - 1.0_f64).abs() < f64::EPSILON {
|
||||
return Command::perform(
|
||||
return Task::perform(
|
||||
load_application(
|
||||
daemon.clone(),
|
||||
info,
|
||||
@ -240,12 +240,12 @@ impl Loader {
|
||||
}
|
||||
Err(e) => {
|
||||
self.step = Step::Error(Box::new(e.into()));
|
||||
return Command::none();
|
||||
return Task::none();
|
||||
}
|
||||
};
|
||||
Command::perform(sync(daemon.clone(), true), Message::Syncing)
|
||||
Task::perform(sync(daemon.clone(), true), Message::Syncing)
|
||||
}
|
||||
_ => Command::none(),
|
||||
_ => Task::none(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -281,7 +281,7 @@ impl Loader {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update(&mut self, message: Message) -> Command<Message> {
|
||||
pub fn update(&mut self, message: Message) -> Task<Message> {
|
||||
match message {
|
||||
Message::View(ViewMessage::Retry) => {
|
||||
let (loader, cmd) = Self::new(
|
||||
@ -299,21 +299,21 @@ impl Loader {
|
||||
Message::BitcoindLog(log) => self.on_log(log),
|
||||
Message::Synced(Err(e)) => {
|
||||
self.step = Step::Error(Box::new(e));
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
Message::Failure(_) => {
|
||||
self.daemon_started = false;
|
||||
Command::none()
|
||||
Task::none()
|
||||
}
|
||||
Message::None => Command::none(),
|
||||
_ => Command::none(),
|
||||
Message::None => Task::none(),
|
||||
_ => Task::none(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn subscription(&self) -> Subscription<Message> {
|
||||
if self.internal_bitcoind.is_some() {
|
||||
let log_path = internal_bitcoind_debug_log_path(&self.datadir_path, self.network);
|
||||
iced::subscription::unfold(0, log_path, move |log_path| async move {
|
||||
iced::Subscription::unfold(0, log_path, move |log_path| async move {
|
||||
// Reduce the io load.
|
||||
tokio::time::sleep(Duration::from_millis(500)).await;
|
||||
|
||||
@ -456,14 +456,14 @@ pub fn view(step: &Step) -> Element<ViewMessage> {
|
||||
} else {
|
||||
SYNCING_PROGRESS_1
|
||||
}))
|
||||
.push(p2_regular(bitcoind_logs).style(color::GREY_3)),
|
||||
.push(p2_regular(bitcoind_logs).color(color::GREY_3)),
|
||||
),
|
||||
Step::Error(error) => cover(
|
||||
Some(("Error while starting the internal daemon", error)),
|
||||
Column::new()
|
||||
.spacing(20)
|
||||
.width(Length::Fill)
|
||||
.align_items(Alignment::Center)
|
||||
.align_x(Alignment::Center)
|
||||
.push(icon::plug_icon().size(100).width(Length::Fixed(300.0)))
|
||||
.push(
|
||||
if matches!(
|
||||
@ -500,10 +500,8 @@ pub fn cover<'a, T: 'a + Clone, C: Into<Element<'a, T>>>(
|
||||
.push_maybe(warn.map(|w| notification::warning(w.0.to_string(), w.1.to_string())))
|
||||
.push(
|
||||
Container::new(content)
|
||||
.width(iced::Length::Fill)
|
||||
.height(iced::Length::Fill)
|
||||
.center_x()
|
||||
.center_y()
|
||||
.center_x(iced::Length::Fill)
|
||||
.center_y(iced::Length::Fill)
|
||||
.padding(50),
|
||||
)
|
||||
.into()
|
||||
|
||||
@ -10,7 +10,7 @@ use iced::{
|
||||
event::{self, Event},
|
||||
executor, keyboard,
|
||||
widget::{focus_next, focus_previous},
|
||||
Application, Command, Settings, Size, Subscription,
|
||||
Application, Settings, Size, Subscription, Task,
|
||||
};
|
||||
use tracing::{error, info};
|
||||
use tracing_subscriber::filter::LevelFilter;
|
||||
@ -152,10 +152,10 @@ impl Application for GUI {
|
||||
}
|
||||
}
|
||||
|
||||
fn new((config, log_level): (Config, Option<LevelFilter>)) -> (GUI, Command<Self::Message>) {
|
||||
fn new((config, log_level): (Config, Option<LevelFilter>)) -> (GUI, Task<Self::Message>) {
|
||||
let logger = Logger::setup(log_level.unwrap_or(LevelFilter::INFO));
|
||||
let mut cmds = font::loads();
|
||||
cmds.push(Command::perform(ctrl_c(), |_| Message::CtrlC));
|
||||
cmds.push(Task::perform(ctrl_c(), |_| Message::CtrlC));
|
||||
let state = match config {
|
||||
Config::Launcher(datadir_path) => {
|
||||
let (launcher, command) = Launcher::new(datadir_path, None);
|
||||
@ -179,11 +179,11 @@ impl Application for GUI {
|
||||
logger,
|
||||
log_level,
|
||||
},
|
||||
Command::batch(cmds),
|
||||
Task::batch(cmds),
|
||||
)
|
||||
}
|
||||
|
||||
fn update(&mut self, message: Self::Message) -> Command<Self::Message> {
|
||||
fn update(&mut self, message: Self::Message) -> Task<Self::Message> {
|
||||
match (&mut self.state, message) {
|
||||
(_, Message::CtrlC)
|
||||
| (_, Message::Event(iced::Event::Window(_, iced::window::Event::CloseRequested))) => {
|
||||
@ -374,7 +374,7 @@ impl Application for GUI {
|
||||
(State::App(i), Message::Run(msg)) => {
|
||||
i.update(*msg).map(|msg| Message::Run(Box::new(msg)))
|
||||
}
|
||||
_ => Command::none(),
|
||||
_ => Task::none(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -433,7 +433,7 @@ pub fn create_app_with_remote_backend(
|
||||
datadir: PathBuf,
|
||||
network: bitcoin::Network,
|
||||
config: app::Config,
|
||||
) -> (app::App, iced::Command<app::Message>) {
|
||||
) -> (app::App, iced::Task<app::Message>) {
|
||||
let hws: Vec<HardwareWalletConfig> = wallet
|
||||
.metadata
|
||||
.ledger_hmacs
|
||||
|
||||
@ -6,6 +6,6 @@ edition = "2021"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
iced = { version = "0.12.1", default-features = false, features = ["svg", "image", "lazy", "qr_code", "advanced", "webgl"] }
|
||||
iced = { version = "0.13.1", default-features = false, features = ["svg", "image", "lazy", "qr_code", "advanced"] }
|
||||
bitcoin = "0.32"
|
||||
chrono = "0.4"
|
||||
|
||||
@ -102,18 +102,18 @@ fn render_amount<'a, T: 'a>(
|
||||
|
||||
let mut child_after = text(after).size(size).bold();
|
||||
if let Some(color_after) = color_after {
|
||||
child_after = child_after.style(color_after);
|
||||
child_after = child_after.color(color_after);
|
||||
}
|
||||
let row = Row::new()
|
||||
.push(text(before).size(size).style(color_before))
|
||||
.push(text(before).size(size).color(color_before))
|
||||
.push(child_after);
|
||||
|
||||
Row::with_children(vec![
|
||||
row.into(),
|
||||
text("BTC").size(size).style(color_before).into(),
|
||||
text("BTC").size(size).color(color_before).into(),
|
||||
])
|
||||
.spacing(spacing)
|
||||
.align_items(iced::Alignment::Center)
|
||||
.align_y(iced::Alignment::Center)
|
||||
}
|
||||
|
||||
// Build the rendering elements for displaying a Bitcoin amount.
|
||||
@ -121,11 +121,11 @@ fn render_unconfirmed_amount<'a, T: 'a>(amount: String, size: u16) -> Row<'a, T>
|
||||
let spacing = if size > P1_SIZE { 10 } else { 5 };
|
||||
|
||||
Row::with_children(vec![
|
||||
text(amount).size(size).style(color::GREY_3).into(),
|
||||
text("BTC").size(size).style(color::GREY_3).into(),
|
||||
text(amount).size(size).color(color::GREY_3).into(),
|
||||
text("BTC").size(size).color(color::GREY_3).into(),
|
||||
])
|
||||
.spacing(spacing)
|
||||
.align_items(iced::Alignment::Center)
|
||||
.align_y(iced::Alignment::Center)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@ -2,63 +2,33 @@ use iced::{widget::tooltip, Length};
|
||||
|
||||
use crate::{component::text, icon, image, theme, widget::*};
|
||||
|
||||
pub struct Badge {
|
||||
icon: crate::widget::Text<'static>,
|
||||
style: theme::Badge,
|
||||
}
|
||||
|
||||
impl Badge {
|
||||
pub fn new(icon: crate::widget::Text<'static>) -> Self {
|
||||
Self {
|
||||
icon,
|
||||
style: theme::Badge::Standard,
|
||||
}
|
||||
}
|
||||
pub fn style(self, style: theme::Badge) -> Self {
|
||||
Self {
|
||||
icon: self.icon,
|
||||
style,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, Message: 'a> From<Badge> for Element<'a, Message> {
|
||||
fn from(badge: Badge) -> Element<'a, Message> {
|
||||
Container::new(badge.icon.width(Length::Fixed(20.0)))
|
||||
.width(Length::Fixed(40.0))
|
||||
.height(Length::Fixed(40.0))
|
||||
.style(theme::Container::Badge(badge.style))
|
||||
.center_x()
|
||||
.center_y()
|
||||
.into()
|
||||
}
|
||||
pub fn badge<T>(icon: crate::widget::Text<'static>) -> Container<'static, T> {
|
||||
Container::new(icon.width(Length::Fixed(20.0)))
|
||||
.style(theme::badge::simple)
|
||||
.center_x(Length::Fixed(40.0))
|
||||
.center_y(Length::Fixed(40.0))
|
||||
}
|
||||
|
||||
pub fn receive<T>() -> Container<'static, T> {
|
||||
Container::new(icon::receive_icon().width(Length::Fixed(20.0)))
|
||||
.width(Length::Fixed(40.0))
|
||||
.height(Length::Fixed(40.0))
|
||||
.style(theme::Container::Badge(theme::Badge::Standard))
|
||||
.center_x()
|
||||
.center_y()
|
||||
.style(theme::badge::simple)
|
||||
.style(theme::badge::simple)
|
||||
.center_x(Length::Fixed(40.0))
|
||||
.center_y(Length::Fixed(40.0))
|
||||
}
|
||||
|
||||
pub fn cycle<T>() -> Container<'static, T> {
|
||||
Container::new(icon::arrow_repeat().width(Length::Fixed(20.0)))
|
||||
.width(Length::Fixed(40.0))
|
||||
.height(Length::Fixed(40.0))
|
||||
.style(theme::Container::Badge(theme::Badge::Standard))
|
||||
.center_x()
|
||||
.center_y()
|
||||
.style(theme::badge::simple)
|
||||
.center_x(Length::Fixed(40.0))
|
||||
.center_y(Length::Fixed(40.0))
|
||||
}
|
||||
|
||||
pub fn spend<T>() -> Container<'static, T> {
|
||||
Container::new(icon::send_icon().width(Length::Fixed(20.0)))
|
||||
.width(Length::Fixed(40.0))
|
||||
.height(Length::Fixed(40.0))
|
||||
.style(theme::Container::Badge(theme::Badge::Standard))
|
||||
.center_x()
|
||||
.center_y()
|
||||
.style(theme::badge::simple)
|
||||
.center_x(Length::Fixed(40.0))
|
||||
.center_y(Length::Fixed(40.0))
|
||||
}
|
||||
|
||||
pub fn coin<T>() -> Container<'static, T> {
|
||||
@ -67,11 +37,9 @@ pub fn coin<T>() -> Container<'static, T> {
|
||||
.height(Length::Fixed(25.0))
|
||||
.width(Length::Fixed(25.0)),
|
||||
)
|
||||
.width(Length::Fixed(40.0))
|
||||
.height(Length::Fixed(40.0))
|
||||
.style(theme::Container::Badge(theme::Badge::Standard))
|
||||
.center_x()
|
||||
.center_y()
|
||||
.style(theme::badge::simple)
|
||||
.center_x(Length::Fixed(40.0))
|
||||
.center_y(Length::Fixed(40.0))
|
||||
}
|
||||
|
||||
pub fn recovery<'a, T: 'a>() -> Container<'a, T> {
|
||||
@ -108,11 +76,10 @@ pub fn badge_pill<'a, T: 'a>(label: &'a str, tooltip: &'a str) -> Container<'a,
|
||||
tooltip::Tooltip::new(
|
||||
Container::new(text::p2_regular(label))
|
||||
.padding(10)
|
||||
.center_x()
|
||||
.style(theme::Container::Pill(theme::Pill::Simple)),
|
||||
.center_x(Length::Shrink)
|
||||
.style(theme::pill::simple),
|
||||
tooltip,
|
||||
tooltip::Position::Top,
|
||||
)
|
||||
.style(theme::Container::Card(theme::Card::Simple))
|
||||
})
|
||||
}
|
||||
|
||||
@ -1,57 +1,55 @@
|
||||
use crate::{color, theme, widget::*};
|
||||
use iced::alignment::{Horizontal, Vertical};
|
||||
use iced::widget::{button, container, row};
|
||||
use iced::Alignment;
|
||||
|
||||
use super::text::text;
|
||||
|
||||
pub fn menu<'a, T: 'a>(icon: Option<Text<'a>>, t: &'static str) -> Button<'a, T> {
|
||||
button::Button::new(content_menu(icon.map(|i| i.style(color::GREY_3)), t).padding(10))
|
||||
.style(theme::Button::Menu(false))
|
||||
button::Button::new(content_menu(icon.map(|i| i.color(color::GREY_3)), t).padding(10))
|
||||
.style(theme::button::menu)
|
||||
}
|
||||
|
||||
pub fn menu_active<'a, T: 'a>(icon: Option<Text<'a>>, t: &'static str) -> Button<'a, T> {
|
||||
button::Button::new(content_menu(icon.map(|i| i.style(color::GREY_3)), t).padding(10))
|
||||
.style(theme::Button::Menu(true))
|
||||
button::Button::new(content_menu(icon.map(|i| i.color(color::GREY_3)), t).padding(10))
|
||||
.style(theme::button::menu_pressed)
|
||||
}
|
||||
|
||||
fn content_menu<'a, T: 'a>(icon: Option<Text<'a>>, t: &'static str) -> Container<'a, T> {
|
||||
match icon {
|
||||
None => container(text(t)).padding(5),
|
||||
Some(i) => {
|
||||
container(row![i, text(t)].spacing(10).align_items(Alignment::Center)).padding(5)
|
||||
}
|
||||
Some(i) => container(row![i, text(t)].spacing(10).align_y(Vertical::Center)).padding(5),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn alert<'a, T: 'a>(icon: Option<Text<'a>>, t: &'static str) -> Button<'a, T> {
|
||||
button::Button::new(content(icon, t)).style(theme::Button::Destructive)
|
||||
button::Button::new(content(icon, t)).style(theme::button::destructive)
|
||||
}
|
||||
|
||||
pub fn primary<'a, T: 'a>(icon: Option<Text<'a>>, t: &'static str) -> Button<'a, T> {
|
||||
button::Button::new(content(icon, t)).style(theme::Button::Primary)
|
||||
button::Button::new(content(icon, t)).style(theme::button::primary)
|
||||
}
|
||||
|
||||
pub fn transparent<'a, T: 'a>(icon: Option<Text<'a>>, t: &'static str) -> Button<'a, T> {
|
||||
button::Button::new(content(icon, t)).style(theme::Button::Transparent)
|
||||
button::Button::new(content(icon, t)).style(theme::button::container)
|
||||
}
|
||||
|
||||
pub fn secondary<'a, T: 'a>(icon: Option<Text<'a>>, t: &'static str) -> Button<'a, T> {
|
||||
button::Button::new(content(icon, t)).style(theme::Button::Secondary)
|
||||
button::Button::new(content(icon, t)).style(theme::button::secondary)
|
||||
}
|
||||
|
||||
pub fn border<'a, T: 'a>(icon: Option<Text<'a>>, t: &'static str) -> Button<'a, T> {
|
||||
button::Button::new(content(icon, t)).style(theme::Button::Border)
|
||||
button::Button::new(content(icon, t)).style(theme::button::secondary)
|
||||
}
|
||||
|
||||
pub fn transparent_border<'a, T: 'a>(icon: Option<Text<'a>>, t: &'static str) -> Button<'a, T> {
|
||||
button(content(icon, t)).style(theme::Button::TransparentBorder)
|
||||
button(content(icon, t)).style(theme::button::container_border)
|
||||
}
|
||||
|
||||
fn content<'a, T: 'a>(icon: Option<Text<'a>>, t: &'static str) -> Container<'a, T> {
|
||||
match icon {
|
||||
None => container(text(t)).center_x().padding(5),
|
||||
Some(i) => container(row![i, text(t)].spacing(10).align_items(Alignment::Center))
|
||||
.center_x()
|
||||
None => container(text(t)).align_x(Horizontal::Center).padding(5),
|
||||
Some(i) => container(row![i, text(t)].spacing(10).align_y(Vertical::Center))
|
||||
.align_x(Horizontal::Center)
|
||||
.padding(5),
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,19 +3,19 @@ use crate::{color, component::text::text, icon, theme, widget::*};
|
||||
pub fn modal<'a, T: 'a, C: Into<Element<'a, T>>>(content: C) -> Container<'a, T> {
|
||||
Container::new(content)
|
||||
.padding(15)
|
||||
.style(theme::Container::Card(theme::Card::Modal))
|
||||
.style(theme::card::modal)
|
||||
}
|
||||
|
||||
pub fn simple<'a, T: 'a, C: Into<Element<'a, T>>>(content: C) -> Container<'a, T> {
|
||||
Container::new(content)
|
||||
.padding(15)
|
||||
.style(theme::Container::Card(theme::Card::Simple))
|
||||
.style(theme::card::simple)
|
||||
}
|
||||
|
||||
pub fn invalid<'a, T: 'a, C: Into<Element<'a, T>>>(content: C) -> Container<'a, T> {
|
||||
Container::new(content)
|
||||
.padding(15)
|
||||
.style(theme::Container::Card(theme::Card::Invalid))
|
||||
.style(theme::card::invalid)
|
||||
}
|
||||
|
||||
/// display an error card with the message and the error in a tooltip.
|
||||
@ -23,12 +23,12 @@ pub fn warning<'a, T: 'a>(message: String) -> Container<'a, T> {
|
||||
Container::new(
|
||||
Row::new()
|
||||
.spacing(20)
|
||||
.align_items(iced::Alignment::Center)
|
||||
.align_y(iced::Alignment::Center)
|
||||
.push(icon::warning_icon())
|
||||
.push(text(message)),
|
||||
)
|
||||
.padding(15)
|
||||
.style(theme::Container::Card(theme::Card::Warning))
|
||||
.style(theme::card::warning)
|
||||
}
|
||||
|
||||
/// display an error card with the message and the error in a tooltip.
|
||||
@ -37,14 +37,14 @@ pub fn error<'a, T: 'a>(message: &'static str, error: String) -> Container<'a, T
|
||||
iced::widget::tooltip::Tooltip::new(
|
||||
Row::new()
|
||||
.spacing(20)
|
||||
.align_items(iced::Alignment::Center)
|
||||
.push(icon::warning_icon().style(color::RED))
|
||||
.push(text(message).style(color::RED)),
|
||||
.align_y(iced::Alignment::Center)
|
||||
.push(icon::warning_icon().color(color::RED))
|
||||
.push(text(message).color(color::RED)),
|
||||
Text::new(error),
|
||||
iced::widget::tooltip::Position::Bottom,
|
||||
)
|
||||
.style(theme::Container::Card(theme::Card::Error)),
|
||||
.style(theme::card::error),
|
||||
)
|
||||
.padding(15)
|
||||
.style(theme::Container::Card(theme::Card::Error))
|
||||
.style(theme::card::error)
|
||||
}
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
#![allow(deprecated)]
|
||||
|
||||
use iced::{
|
||||
advanced,
|
||||
widget::{column, component, Button, Component},
|
||||
@ -16,7 +18,7 @@ pub struct Collapse<'a, M, H, F, C> {
|
||||
impl<'a, Message, T, H, F, C, Theme, Renderer> Collapse<'a, Message, H, F, C>
|
||||
where
|
||||
Renderer: advanced::Renderer,
|
||||
Theme: iced::widget::button::StyleSheet,
|
||||
Theme: iced::widget::button::Catalog,
|
||||
Message: 'a,
|
||||
T: Into<Message> + Clone + 'a,
|
||||
H: Fn() -> Button<'a, Event<T>, Theme, Renderer> + 'a,
|
||||
@ -53,7 +55,7 @@ where
|
||||
F: Fn() -> Button<'a, Event<T>, Theme, Renderer>,
|
||||
C: Fn() -> Element<'a, T, Theme, Renderer>,
|
||||
Renderer: 'a + advanced::Renderer,
|
||||
Theme: 'a + iced::widget::button::StyleSheet,
|
||||
Theme: 'a + iced::widget::button::Catalog,
|
||||
{
|
||||
type State = Option<bool>;
|
||||
type Event = Event<T>;
|
||||
@ -96,7 +98,7 @@ impl<'a, Message, T, H: 'a, F: 'a, C: 'a, Theme, Renderer> From<Collapse<'a, Mes
|
||||
where
|
||||
Message: 'a,
|
||||
Renderer: 'a + advanced::Renderer,
|
||||
Theme: 'a + iced::widget::button::StyleSheet,
|
||||
Theme: 'a + iced::widget::button::Catalog,
|
||||
T: Into<Message> + Clone + 'a,
|
||||
H: Fn() -> Button<'a, Event<T>, Theme, Renderer>,
|
||||
F: Fn() -> Button<'a, Event<T>, Theme, Renderer>,
|
||||
|
||||
@ -12,39 +12,39 @@ use iced::{
|
||||
|
||||
use chrono::{DateTime, Local, Utc};
|
||||
|
||||
pub fn unconfirmed_outgoing_event<'a, T: Clone + 'a>(
|
||||
label: Option<Text<'a>>,
|
||||
pub fn unconfirmed_outgoing_event<T: Clone + 'static>(
|
||||
label: Option<Text<'static>>,
|
||||
amount: &Amount,
|
||||
msg: T,
|
||||
) -> Container<'a, T> {
|
||||
) -> Container<'static, T> {
|
||||
Container::new(
|
||||
button(
|
||||
row!(
|
||||
row!(badge::spend(), Column::new().push_maybe(label),)
|
||||
.spacing(10)
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.width(Length::Fill),
|
||||
badge::unconfirmed(),
|
||||
row!(text::p1_regular("-"), amount::amount(amount))
|
||||
.spacing(5)
|
||||
.align_items(Alignment::Center),
|
||||
.align_y(Alignment::Center),
|
||||
)
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.padding(5)
|
||||
.spacing(20),
|
||||
)
|
||||
.on_press(msg)
|
||||
.style(theme::Button::TransparentBorder),
|
||||
.style(theme::button::transparent_border),
|
||||
)
|
||||
.style(theme::Container::Card(theme::Card::Simple))
|
||||
.style(theme::card::simple)
|
||||
}
|
||||
|
||||
pub fn confirmed_outgoing_event<'a, T: Clone + 'a>(
|
||||
label: Option<Text<'a>>,
|
||||
pub fn confirmed_outgoing_event<T: Clone + 'static>(
|
||||
label: Option<Text<'static>>,
|
||||
date: DateTime<Utc>,
|
||||
amount: &Amount,
|
||||
msg: T,
|
||||
) -> Container<'a, T> {
|
||||
) -> Container<'static, T> {
|
||||
Container::new(
|
||||
button(
|
||||
row!(
|
||||
@ -56,59 +56,59 @@ pub fn confirmed_outgoing_event<'a, T: Clone + 'a>(
|
||||
.format("%b. %d, %Y - %T")
|
||||
.to_string()
|
||||
)
|
||||
.style(color::GREY_3)
|
||||
.color(color::GREY_3)
|
||||
)
|
||||
)
|
||||
.spacing(10)
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.width(Length::Fill),
|
||||
row!(text::p1_regular("-"), amount::amount(amount))
|
||||
.spacing(5)
|
||||
.align_items(Alignment::Center),
|
||||
.align_y(Alignment::Center),
|
||||
)
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.padding(5)
|
||||
.spacing(20),
|
||||
)
|
||||
.on_press(msg)
|
||||
.style(theme::Button::TransparentBorder),
|
||||
.style(theme::button::transparent_border),
|
||||
)
|
||||
.style(theme::Container::Card(theme::Card::Simple))
|
||||
.style(theme::card::simple)
|
||||
}
|
||||
|
||||
pub fn unconfirmed_incoming_event<'a, T: Clone + 'a>(
|
||||
label: Option<Text<'a>>,
|
||||
pub fn unconfirmed_incoming_event<T: Clone + 'static>(
|
||||
label: Option<Text<'static>>,
|
||||
amount: &Amount,
|
||||
msg: T,
|
||||
) -> Container<'a, T> {
|
||||
) -> Container<'static, T> {
|
||||
Container::new(
|
||||
button(
|
||||
row!(
|
||||
row!(badge::receive(), Column::new().push_maybe(label))
|
||||
.spacing(10)
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.width(Length::Fill),
|
||||
badge::unconfirmed(),
|
||||
row!(text::p1_regular("+"), amount::amount(amount))
|
||||
.spacing(5)
|
||||
.align_items(Alignment::Center),
|
||||
.align_y(Alignment::Center),
|
||||
)
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.padding(5)
|
||||
.spacing(20),
|
||||
)
|
||||
.on_press(msg)
|
||||
.style(theme::Button::TransparentBorder),
|
||||
.style(theme::button::transparent_border),
|
||||
)
|
||||
.style(theme::Container::Card(theme::Card::Simple))
|
||||
.style(theme::card::simple)
|
||||
}
|
||||
|
||||
pub fn confirmed_incoming_event<'a, T: Clone + 'a>(
|
||||
label: Option<Text<'a>>,
|
||||
pub fn confirmed_incoming_event<T: Clone + 'static>(
|
||||
label: Option<Text<'static>>,
|
||||
date: DateTime<Utc>,
|
||||
amount: &Amount,
|
||||
msg: T,
|
||||
) -> Container<'a, T> {
|
||||
) -> Container<'static, T> {
|
||||
Container::new(
|
||||
button(
|
||||
row!(
|
||||
@ -120,22 +120,22 @@ pub fn confirmed_incoming_event<'a, T: Clone + 'a>(
|
||||
.format("%b. %d, %Y - %T")
|
||||
.to_string()
|
||||
)
|
||||
.style(color::GREY_3)
|
||||
.color(color::GREY_3)
|
||||
)
|
||||
)
|
||||
.spacing(10)
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.width(Length::Fill),
|
||||
row!(text::p1_regular("+"), amount::amount(amount))
|
||||
.spacing(5)
|
||||
.align_items(Alignment::Center),
|
||||
.align_y(Alignment::Center),
|
||||
)
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.padding(5)
|
||||
.spacing(20),
|
||||
)
|
||||
.on_press(msg)
|
||||
.style(theme::Button::TransparentBorder),
|
||||
.style(theme::button::transparent_border),
|
||||
)
|
||||
.style(theme::Container::Card(theme::Card::Simple))
|
||||
.style(theme::card::simple)
|
||||
}
|
||||
|
||||
@ -110,13 +110,13 @@ impl<'a, Message: 'a + Clone> From<Form<'a, Message>> for Element<'a, Message> {
|
||||
Container::new(
|
||||
Column::new()
|
||||
.push(if !form.valid {
|
||||
form.input.style(theme::Form::Invalid)
|
||||
form.input.style(theme::text_input::invalid)
|
||||
} else {
|
||||
form.input
|
||||
})
|
||||
.push_maybe(if !form.valid {
|
||||
form.warning
|
||||
.map(|message| text::caption(message).style(color::RED))
|
||||
.map(|message| text::caption(message).color(color::RED))
|
||||
} else {
|
||||
None
|
||||
})
|
||||
|
||||
@ -8,7 +8,7 @@ use std::fmt::Display;
|
||||
|
||||
pub fn locked_hardware_wallet<'a, T: 'a, K: Display>(
|
||||
kind: K,
|
||||
pairing_code: Option<impl Into<Cow<'a, str>>>,
|
||||
pairing_code: Option<impl Into<Cow<'a, str>> + Display>,
|
||||
) -> Container<'a, T> {
|
||||
Container::new(
|
||||
column(vec![
|
||||
@ -38,7 +38,7 @@ pub fn supported_hardware_wallet<'a, T: 'a, K: Display, V: Display, F: Display>(
|
||||
kind: K,
|
||||
version: Option<V>,
|
||||
fingerprint: F,
|
||||
alias: Option<impl Into<Cow<'a, str>>>,
|
||||
alias: Option<impl Into<Cow<'a, str>> + Display>,
|
||||
) -> Container<'a, T> {
|
||||
Container::new(
|
||||
column(vec![
|
||||
@ -58,12 +58,12 @@ pub fn supported_hardware_wallet<'a, T: 'a, K: Display, V: Display, F: Display>(
|
||||
.padding(10)
|
||||
}
|
||||
|
||||
pub fn warning_hardware_wallet<'a, T: 'a, K: Display, V: Display, F: Display>(
|
||||
pub fn warning_hardware_wallet<'a, T: 'static, K: Display, V: Display, F: Display>(
|
||||
kind: K,
|
||||
version: Option<V>,
|
||||
fingerprint: F,
|
||||
alias: Option<impl Into<Cow<'a, str>>>,
|
||||
warning: &'static str,
|
||||
alias: Option<impl Into<Cow<'a, str>> + Display>,
|
||||
warning: &'a str,
|
||||
) -> Container<'a, T> {
|
||||
container(
|
||||
row(vec![
|
||||
@ -83,14 +83,14 @@ pub fn warning_hardware_wallet<'a, T: 'a, K: Display, V: Display, F: Display>(
|
||||
.into(),
|
||||
column(vec![tooltip::Tooltip::new(
|
||||
icon::warning_icon(),
|
||||
warning,
|
||||
iced::widget::text!("{}", warning),
|
||||
tooltip::Position::Bottom,
|
||||
)
|
||||
.style(theme::Container::Card(theme::Card::Simple))
|
||||
.style(theme::card::simple)
|
||||
.into()])
|
||||
.into(),
|
||||
])
|
||||
.align_items(Alignment::Center),
|
||||
.align_y(Alignment::Center),
|
||||
)
|
||||
.padding(10)
|
||||
}
|
||||
@ -119,7 +119,7 @@ pub fn unimplemented_method_hardware_wallet<'a, T: 'a, K: Display, V: Display, F
|
||||
message,
|
||||
tooltip::Position::Bottom,
|
||||
)
|
||||
.style(theme::Container::Card(theme::Card::Simple)),
|
||||
.style(theme::card::simple),
|
||||
)
|
||||
.width(Length::Fill)
|
||||
}
|
||||
@ -147,7 +147,7 @@ pub fn unrelated_hardware_wallet<'a, T: 'a, K: Display, V: Display, F: Display>(
|
||||
"This signer does not have a key in this wallet.",
|
||||
tooltip::Position::Bottom,
|
||||
)
|
||||
.style(theme::Container::Card(theme::Card::Simple)),
|
||||
.style(theme::card::simple),
|
||||
)
|
||||
.width(Length::Fill)
|
||||
}
|
||||
@ -156,7 +156,7 @@ pub fn processing_hardware_wallet<'a, T: 'a, K: Display, V: Display, F: Display>
|
||||
kind: K,
|
||||
version: Option<V>,
|
||||
fingerprint: F,
|
||||
alias: Option<impl Into<Cow<'a, str>>>,
|
||||
alias: Option<impl Into<Cow<'a, str>> + Display>,
|
||||
) -> Container<'a, T> {
|
||||
container(
|
||||
row(vec![
|
||||
@ -180,41 +180,48 @@ pub fn processing_hardware_wallet<'a, T: 'a, K: Display, V: Display, F: Display>
|
||||
])
|
||||
.into(),
|
||||
])
|
||||
.align_items(Alignment::Center),
|
||||
.align_y(Alignment::Center),
|
||||
)
|
||||
.padding(10)
|
||||
}
|
||||
|
||||
pub fn selected_hardware_wallet<'a, T: 'a, K: Display, V: Display, F: Display>(
|
||||
pub fn selected_hardware_wallet<'a, T: 'static, K: Display, V: Display, F: Display>(
|
||||
kind: K,
|
||||
version: Option<V>,
|
||||
fingerprint: F,
|
||||
alias: Option<impl Into<Cow<'a, str>>>,
|
||||
alias: Option<impl Into<Cow<'a, str>> + Display>,
|
||||
warning: Option<&'static str>,
|
||||
) -> Container<'a, T> {
|
||||
container(
|
||||
Row::new()
|
||||
.push(
|
||||
column(vec![
|
||||
Row::new()
|
||||
.spacing(5)
|
||||
.push_maybe(alias.map(|a| text::p1_bold(a)))
|
||||
.push(text::p1_regular(format!("#{}", fingerprint)))
|
||||
.into(),
|
||||
Row::new()
|
||||
.spacing(5)
|
||||
.push(text::caption(kind.to_string()))
|
||||
.push_maybe(version.map(|v| text::caption(v.to_string())))
|
||||
.into(),
|
||||
])
|
||||
.width(Length::Fill),
|
||||
)
|
||||
.push_maybe(warning.map(|w| {
|
||||
tooltip::Tooltip::new(icon::warning_icon(), w, tooltip::Position::Bottom)
|
||||
.style(theme::Container::Card(theme::Card::Simple))
|
||||
}))
|
||||
.push(image::success_mark_icon().width(Length::Fixed(50.0)))
|
||||
.align_items(Alignment::Center),
|
||||
row(vec![
|
||||
column(vec![
|
||||
Row::new()
|
||||
.spacing(5)
|
||||
.push_maybe(alias.map(text::p1_bold))
|
||||
.push(text::p1_regular(format!("#{}", fingerprint)))
|
||||
.into(),
|
||||
Row::new()
|
||||
.spacing(5)
|
||||
.push(text::caption(kind.to_string()))
|
||||
.push_maybe(version.map(|v| text::caption(v)))
|
||||
.into(),
|
||||
])
|
||||
.width(Length::Fill)
|
||||
.into(),
|
||||
if let Some(w) = warning {
|
||||
tooltip::Tooltip::new(
|
||||
icon::warning_icon(),
|
||||
iced::widget::text!("{}", w),
|
||||
tooltip::Position::Bottom,
|
||||
)
|
||||
.style(theme::card::simple)
|
||||
.into()
|
||||
} else {
|
||||
Row::new().into()
|
||||
},
|
||||
image::success_mark_icon().width(Length::Fixed(50.0)).into(),
|
||||
])
|
||||
.align_y(Alignment::Center),
|
||||
)
|
||||
.padding(10)
|
||||
}
|
||||
@ -223,7 +230,7 @@ pub fn sign_success_hardware_wallet<'a, T: 'a, K: Display, V: Display, F: Displa
|
||||
kind: K,
|
||||
version: Option<V>,
|
||||
fingerprint: F,
|
||||
alias: Option<impl Into<Cow<'a, str>>>,
|
||||
alias: Option<impl Into<Cow<'a, str>> + Display>,
|
||||
) -> Container<'a, T> {
|
||||
container(
|
||||
row(vec![
|
||||
@ -242,14 +249,14 @@ pub fn sign_success_hardware_wallet<'a, T: 'a, K: Display, V: Display, F: Displa
|
||||
.width(Length::Fill)
|
||||
.into(),
|
||||
row(vec![
|
||||
text::p1_regular("Signed").style(color::GREEN).into(),
|
||||
text::p1_regular("Signed").color(color::GREEN).into(),
|
||||
image::success_mark_icon().width(Length::Fixed(50.0)).into(),
|
||||
])
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.spacing(5)
|
||||
.into(),
|
||||
])
|
||||
.align_items(Alignment::Center),
|
||||
.align_y(Alignment::Center),
|
||||
)
|
||||
.padding(10)
|
||||
}
|
||||
@ -258,7 +265,7 @@ pub fn registration_success_hardware_wallet<'a, T: 'a, K: Display, V: Display, F
|
||||
kind: K,
|
||||
version: Option<V>,
|
||||
fingerprint: F,
|
||||
alias: Option<impl Into<Cow<'a, str>>>,
|
||||
alias: Option<impl Into<Cow<'a, str>> + Display>,
|
||||
) -> Container<'a, T> {
|
||||
container(
|
||||
row(vec![
|
||||
@ -277,19 +284,19 @@ pub fn registration_success_hardware_wallet<'a, T: 'a, K: Display, V: Display, F
|
||||
.width(Length::Fill)
|
||||
.into(),
|
||||
row(vec![
|
||||
text::p1_regular("Registered").style(color::GREEN).into(),
|
||||
text::p1_regular("Registered").color(color::GREEN).into(),
|
||||
image::success_mark_icon().width(Length::Fixed(50.0)).into(),
|
||||
])
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.spacing(5)
|
||||
.into(),
|
||||
])
|
||||
.align_items(Alignment::Center),
|
||||
.align_y(Alignment::Center),
|
||||
)
|
||||
.padding(10)
|
||||
}
|
||||
|
||||
pub fn wrong_network_hardware_wallet<'a, T: 'a, K: Display, V: Display>(
|
||||
pub fn wrong_network_hardware_wallet<'a, T: 'static, K: Display, V: Display>(
|
||||
kind: K,
|
||||
version: Option<V>,
|
||||
) -> Container<'a, T> {
|
||||
@ -313,15 +320,15 @@ pub fn wrong_network_hardware_wallet<'a, T: 'a, K: Display, V: Display>(
|
||||
"The wrong bitcoin application is open or the device was initialized with the wrong network",
|
||||
tooltip::Position::Bottom,
|
||||
)
|
||||
.style(theme::Container::Card(theme::Card::Simple))
|
||||
.style(theme::card::simple)
|
||||
.into(),
|
||||
])
|
||||
.align_items(Alignment::Center),
|
||||
.align_y(Alignment::Center),
|
||||
)
|
||||
.padding(10)
|
||||
}
|
||||
|
||||
pub fn unsupported_hardware_wallet<'a, T: 'a, K: Display, V: Display>(
|
||||
pub fn unsupported_hardware_wallet<'a, T: 'static, K: Display, V: Display>(
|
||||
kind: K,
|
||||
version: Option<V>,
|
||||
) -> Container<'a, T> {
|
||||
@ -345,15 +352,15 @@ pub fn unsupported_hardware_wallet<'a, T: 'a, K: Display, V: Display>(
|
||||
"Make sure your device is unlocked and a supported Bitcoin application is opened.",
|
||||
tooltip::Position::Bottom,
|
||||
)
|
||||
.style(theme::Container::Card(theme::Card::Simple))
|
||||
.style(theme::card::simple)
|
||||
.into(),
|
||||
])
|
||||
.align_items(Alignment::Center),
|
||||
.align_y(Alignment::Center),
|
||||
)
|
||||
.padding(10)
|
||||
}
|
||||
|
||||
pub fn unsupported_version_hardware_wallet<'a, T: 'a, K: Display, V: Display, S: Display>(
|
||||
pub fn unsupported_version_hardware_wallet<'a, T: 'static, K: Display, V: Display, S: Display>(
|
||||
kind: K,
|
||||
version: Option<V>,
|
||||
requested_version: S,
|
||||
@ -376,17 +383,17 @@ pub fn unsupported_version_hardware_wallet<'a, T: 'a, K: Display, V: Display, S:
|
||||
"Please upgrade firmware",
|
||||
tooltip::Position::Bottom,
|
||||
)
|
||||
.style(theme::Container::Card(theme::Card::Simple))
|
||||
.style(theme::card::simple)
|
||||
.into(),
|
||||
])
|
||||
.align_items(Alignment::Center),
|
||||
.align_y(Alignment::Center),
|
||||
)
|
||||
.padding(10)
|
||||
}
|
||||
|
||||
pub fn sign_success_hot_signer<'a, T: 'a, F: Display>(
|
||||
fingerprint: F,
|
||||
alias: Option<impl Into<Cow<'a, str>>>,
|
||||
alias: Option<impl Into<Cow<'a, str>> + Display>,
|
||||
) -> Container<'a, T> {
|
||||
container(
|
||||
row(vec![
|
||||
@ -404,21 +411,21 @@ pub fn sign_success_hot_signer<'a, T: 'a, F: Display>(
|
||||
.width(Length::Fill)
|
||||
.into(),
|
||||
row(vec![
|
||||
text::p1_regular("Signed").style(color::GREEN).into(),
|
||||
text::p1_regular("Signed").color(color::GREEN).into(),
|
||||
image::success_mark_icon().width(Length::Fixed(50.0)).into(),
|
||||
])
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.spacing(5)
|
||||
.into(),
|
||||
])
|
||||
.align_items(Alignment::Center),
|
||||
.align_y(Alignment::Center),
|
||||
)
|
||||
.padding(10)
|
||||
}
|
||||
|
||||
pub fn selected_hot_signer<'a, T: 'a, F: Display>(
|
||||
fingerprint: F,
|
||||
alias: Option<impl Into<Cow<'a, str>>>,
|
||||
alias: Option<impl Into<Cow<'a, str>> + Display>,
|
||||
) -> Container<'a, T> {
|
||||
container(
|
||||
row(vec![
|
||||
@ -440,14 +447,14 @@ pub fn selected_hot_signer<'a, T: 'a, F: Display>(
|
||||
.into(),
|
||||
image::success_mark_icon().width(Length::Fixed(50.0)).into(),
|
||||
])
|
||||
.align_items(Alignment::Center),
|
||||
.align_y(Alignment::Center),
|
||||
)
|
||||
.padding(10)
|
||||
}
|
||||
|
||||
pub fn unselected_hot_signer<'a, T: 'a, F: Display>(
|
||||
fingerprint: F,
|
||||
alias: Option<impl Into<Cow<'a, str>>>,
|
||||
alias: Option<impl Into<Cow<'a, str>> + Display>,
|
||||
) -> Container<'a, T> {
|
||||
Container::new(
|
||||
column(vec![
|
||||
@ -471,7 +478,7 @@ pub fn unselected_hot_signer<'a, T: 'a, F: Display>(
|
||||
|
||||
pub fn hot_signer<'a, T: 'a, F: Display>(
|
||||
fingerprint: F,
|
||||
alias: Option<impl Into<Cow<'a, str>>>,
|
||||
alias: Option<impl Into<Cow<'a, str>> + Display>,
|
||||
) -> Container<'a, T> {
|
||||
Container::new(
|
||||
column(vec![
|
||||
|
||||
@ -24,7 +24,7 @@ use self::text::Text;
|
||||
|
||||
pub fn separation<'a, T: 'a>() -> Container<'a, T> {
|
||||
Container::new(Column::new().push(text::text(" ")))
|
||||
.style(theme::Container::Border)
|
||||
.style(theme::container::border)
|
||||
.height(Length::Fixed(1.0))
|
||||
}
|
||||
|
||||
@ -44,10 +44,9 @@ pub fn network_banner<'a, T: 'a>(network: Network) -> Container<'a, T> {
|
||||
)
|
||||
.push(text::text(", COINS HAVE "))
|
||||
.push(text::text("NO VALUE").bold())
|
||||
.align_items(iced::Alignment::Center),
|
||||
.align_y(iced::Alignment::Center),
|
||||
)
|
||||
.padding(5)
|
||||
.width(Length::Fill)
|
||||
.center_x()
|
||||
.style(theme::Container::Banner)
|
||||
.center_x(Length::Fill)
|
||||
.style(theme::banner::network)
|
||||
}
|
||||
|
||||
@ -147,7 +147,7 @@ where
|
||||
state: &mut Tree,
|
||||
layout: Layout<'_>,
|
||||
renderer: &Renderer,
|
||||
operation: &mut dyn widget::Operation<Message>,
|
||||
operation: &mut dyn widget::Operation,
|
||||
) {
|
||||
self.base
|
||||
.as_widget()
|
||||
@ -249,7 +249,7 @@ where
|
||||
&mut self,
|
||||
layout: Layout<'_>,
|
||||
renderer: &Renderer,
|
||||
operation: &mut dyn widget::Operation<Message>,
|
||||
operation: &mut dyn widget::Operation,
|
||||
) {
|
||||
self.content.as_widget().operate(
|
||||
self.tree,
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
use std::borrow::Cow;
|
||||
use std::fmt::Display;
|
||||
|
||||
use crate::{
|
||||
@ -20,41 +19,41 @@ pub fn warning<'a, T: 'a + Clone>(message: String, error: String) -> Container<'
|
||||
Row::new()
|
||||
.push(
|
||||
Container::new(
|
||||
text::p1_bold(message_clone.to_string()).style(color::LIGHT_BLACK),
|
||||
text::p1_bold(message_clone.to_string()).color(color::LIGHT_BLACK),
|
||||
)
|
||||
.width(Length::Fill),
|
||||
)
|
||||
.push(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.spacing(10)
|
||||
.push(text::p1_bold("Learn more").style(color::LIGHT_BLACK))
|
||||
.push(icon::collapse_icon().style(color::LIGHT_BLACK)),
|
||||
.push(text::p1_bold("Learn more").color(color::LIGHT_BLACK))
|
||||
.push(icon::collapse_icon().color(color::LIGHT_BLACK)),
|
||||
),
|
||||
)
|
||||
.style(theme::Button::Transparent)
|
||||
.style(theme::button::transparent)
|
||||
},
|
||||
move || {
|
||||
Button::new(
|
||||
Row::new()
|
||||
.push(
|
||||
Container::new(text::p1_bold(message.to_owned()).style(color::LIGHT_BLACK))
|
||||
Container::new(text::p1_bold(message.to_owned()).color(color::LIGHT_BLACK))
|
||||
.width(Length::Fill),
|
||||
)
|
||||
.push(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.spacing(10)
|
||||
.push(text::p1_bold("Learn more").style(color::LIGHT_BLACK))
|
||||
.push(icon::collapsed_icon().style(color::LIGHT_BLACK)),
|
||||
.push(text::p1_bold("Learn more").color(color::LIGHT_BLACK))
|
||||
.push(icon::collapsed_icon().color(color::LIGHT_BLACK)),
|
||||
),
|
||||
)
|
||||
.style(theme::Button::Transparent)
|
||||
.style(theme::button::transparent)
|
||||
},
|
||||
move || Element::<'a, T>::from(text::p2_regular(error.to_owned())),
|
||||
)))
|
||||
.padding(15)
|
||||
.style(theme::Container::Card(theme::Card::Warning))
|
||||
.style(theme::card::warning)
|
||||
.width(Length::Fill)
|
||||
}
|
||||
|
||||
@ -62,14 +61,14 @@ pub fn processing_hardware_wallet<'a, T: 'a, K: Display, V: Display, F: Display>
|
||||
kind: K,
|
||||
version: Option<V>,
|
||||
fingerprint: F,
|
||||
alias: Option<impl Into<Cow<'a, str>>>,
|
||||
alias: Option<&'a str>,
|
||||
) -> Container<'a, T> {
|
||||
container(
|
||||
row(vec![
|
||||
column(vec![
|
||||
Row::new()
|
||||
.spacing(5)
|
||||
.push_maybe(alias.map(|a| text::p1_bold(a)))
|
||||
.push_maybe(alias.map(text::p1_bold))
|
||||
.push(text::p1_regular(format!("#{}", fingerprint)))
|
||||
.into(),
|
||||
Row::new()
|
||||
@ -86,9 +85,9 @@ pub fn processing_hardware_wallet<'a, T: 'a, K: Display, V: Display, F: Display>
|
||||
])
|
||||
.into(),
|
||||
])
|
||||
.align_items(Alignment::Center),
|
||||
.align_y(Alignment::Center),
|
||||
)
|
||||
.style(theme::Container::Notification(theme::Notification::Pending))
|
||||
.style(theme::notification::pending)
|
||||
.padding(10)
|
||||
}
|
||||
|
||||
@ -103,40 +102,40 @@ pub fn processing_hardware_wallet_error<'a, T: 'a + Clone>(
|
||||
Row::new()
|
||||
.push(
|
||||
Container::new(
|
||||
text::p1_bold(message_clone.to_string()).style(color::LIGHT_BLACK),
|
||||
text::p1_bold(message_clone.to_string()).color(color::LIGHT_BLACK),
|
||||
)
|
||||
.width(Length::Fill),
|
||||
)
|
||||
.push(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.spacing(10)
|
||||
.push(text::p1_bold("Learn more").style(color::LIGHT_BLACK))
|
||||
.push(icon::collapse_icon().style(color::LIGHT_BLACK)),
|
||||
.push(text::p1_bold("Learn more").color(color::LIGHT_BLACK))
|
||||
.push(icon::collapse_icon().color(color::LIGHT_BLACK)),
|
||||
),
|
||||
)
|
||||
.style(theme::Button::Transparent)
|
||||
.style(theme::button::transparent)
|
||||
},
|
||||
move || {
|
||||
Button::new(
|
||||
Row::new()
|
||||
.push(
|
||||
Container::new(text::p1_bold(message.to_owned()).style(color::LIGHT_BLACK))
|
||||
Container::new(text::p1_bold(message.to_owned()).color(color::LIGHT_BLACK))
|
||||
.width(Length::Fill),
|
||||
)
|
||||
.push(
|
||||
Row::new()
|
||||
.align_items(Alignment::Center)
|
||||
.align_y(Alignment::Center)
|
||||
.spacing(10)
|
||||
.push(text::p1_bold("Learn more").style(color::LIGHT_BLACK))
|
||||
.push(icon::collapsed_icon().style(color::LIGHT_BLACK)),
|
||||
.push(text::p1_bold("Learn more").color(color::LIGHT_BLACK))
|
||||
.push(icon::collapsed_icon().color(color::LIGHT_BLACK)),
|
||||
),
|
||||
)
|
||||
.style(theme::Button::Transparent)
|
||||
.style(theme::button::transparent)
|
||||
},
|
||||
move || Element::<'a, T>::from(text::p2_regular(error.to_owned())),
|
||||
)))
|
||||
.padding(10)
|
||||
.style(theme::Container::Notification(theme::Notification::Error))
|
||||
.style(theme::notification::error)
|
||||
.width(Length::Fill)
|
||||
}
|
||||
|
||||
@ -108,7 +108,7 @@ where
|
||||
_viewport: &Rectangle,
|
||||
) -> event::Status {
|
||||
let state = tree.state.downcast_mut::<CarouselState>();
|
||||
if let Event::Window(_, window::Event::RedrawRequested(now)) = event {
|
||||
if let Event::Window(window::Event::RedrawRequested(now)) = event {
|
||||
if now.duration_since(state.last_transition) > self.interval {
|
||||
state.last_transition = now;
|
||||
state.current = (state.current + 1) % self.children.len();
|
||||
@ -172,7 +172,7 @@ pub fn typing_text_carousel<'a, Message, Theme>(
|
||||
text_builder: impl Fn(&'a str) -> iced::widget::Text<'a, Theme, Renderer>,
|
||||
) -> Carousel<'a, Message, Theme>
|
||||
where
|
||||
Theme: 'a + iced::widget::text::StyleSheet,
|
||||
Theme: 'a + iced::widget::text::Catalog,
|
||||
{
|
||||
let mut children = Vec::new();
|
||||
if show_empty {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
use crate::{font, theme::Theme};
|
||||
use iced::advanced::text::Shaping;
|
||||
use std::borrow::Cow;
|
||||
use std::fmt::Display;
|
||||
|
||||
pub const H1_SIZE: u16 = 40;
|
||||
pub const H2_SIZE: u16 = 29;
|
||||
@ -11,98 +11,98 @@ pub const P1_SIZE: u16 = 16;
|
||||
pub const P2_SIZE: u16 = 14;
|
||||
pub const CAPTION_SIZE: u16 = 12;
|
||||
|
||||
pub fn h1<'a>(content: impl Into<Cow<'a, str>>) -> iced::widget::Text<'a, Theme> {
|
||||
iced::widget::Text::new(content)
|
||||
pub fn h1<'a>(content: impl Display) -> iced::widget::Text<'a, Theme> {
|
||||
iced::widget::text!("{}", content)
|
||||
.shaping(Shaping::Advanced)
|
||||
.font(font::BOLD)
|
||||
.size(H1_SIZE)
|
||||
}
|
||||
|
||||
pub fn h2<'a>(content: impl Into<Cow<'a, str>>) -> iced::widget::Text<'a, Theme> {
|
||||
iced::widget::Text::new(content)
|
||||
pub fn h2<'a>(content: impl Display) -> iced::widget::Text<'a, Theme> {
|
||||
iced::widget::text!("{}", content)
|
||||
.shaping(Shaping::Advanced)
|
||||
.font(font::BOLD)
|
||||
.size(H2_SIZE)
|
||||
}
|
||||
|
||||
pub fn h3<'a>(content: impl Into<Cow<'a, str>>) -> iced::widget::Text<'a, Theme> {
|
||||
iced::widget::Text::new(content)
|
||||
pub fn h3<'a>(content: impl Display) -> iced::widget::Text<'a, Theme> {
|
||||
iced::widget::text!("{}", content)
|
||||
.shaping(Shaping::Advanced)
|
||||
.font(font::BOLD)
|
||||
.size(H3_SIZE)
|
||||
}
|
||||
|
||||
pub fn h4_bold<'a>(content: impl Into<Cow<'a, str>>) -> iced::widget::Text<'a, Theme> {
|
||||
iced::widget::Text::new(content)
|
||||
pub fn h4_bold<'a>(content: impl Display) -> iced::widget::Text<'a, Theme> {
|
||||
iced::widget::text!("{}", content)
|
||||
.shaping(Shaping::Advanced)
|
||||
.font(font::BOLD)
|
||||
.size(H4_SIZE)
|
||||
}
|
||||
|
||||
pub fn h4_regular<'a>(content: impl Into<Cow<'a, str>>) -> iced::widget::Text<'a, Theme> {
|
||||
iced::widget::Text::new(content)
|
||||
pub fn h4_regular<'a>(content: impl Display) -> iced::widget::Text<'a, Theme> {
|
||||
iced::widget::text!("{}", content)
|
||||
.shaping(Shaping::Advanced)
|
||||
.font(font::REGULAR)
|
||||
.size(H4_SIZE)
|
||||
}
|
||||
|
||||
pub fn h5_medium<'a>(content: impl Into<Cow<'a, str>>) -> iced::widget::Text<'a, Theme> {
|
||||
iced::widget::Text::new(content)
|
||||
pub fn h5_medium<'a>(content: impl Display) -> iced::widget::Text<'a, Theme> {
|
||||
iced::widget::text!("{}", content)
|
||||
.shaping(Shaping::Advanced)
|
||||
.font(font::MEDIUM)
|
||||
.size(H5_SIZE)
|
||||
}
|
||||
|
||||
pub fn h5_regular<'a>(content: impl Into<Cow<'a, str>>) -> iced::widget::Text<'a, Theme> {
|
||||
iced::widget::Text::new(content)
|
||||
pub fn h5_regular<'a>(content: impl Display) -> iced::widget::Text<'a, Theme> {
|
||||
iced::widget::text!("{}", content)
|
||||
.shaping(Shaping::Advanced)
|
||||
.font(font::REGULAR)
|
||||
.size(H5_SIZE)
|
||||
}
|
||||
|
||||
pub fn p1_bold<'a>(content: impl Into<Cow<'a, str>>) -> iced::widget::Text<'a, Theme> {
|
||||
iced::widget::Text::new(content)
|
||||
pub fn p1_bold<'a>(content: impl Display) -> iced::widget::Text<'a, Theme> {
|
||||
iced::widget::text!("{}", content)
|
||||
.shaping(Shaping::Advanced)
|
||||
.font(font::BOLD)
|
||||
.size(P1_SIZE)
|
||||
}
|
||||
|
||||
pub fn p1_medium<'a>(content: impl Into<Cow<'a, str>>) -> iced::widget::Text<'a, Theme> {
|
||||
iced::widget::Text::new(content)
|
||||
pub fn p1_medium<'a>(content: impl Display) -> iced::widget::Text<'a, Theme> {
|
||||
iced::widget::text!("{}", content)
|
||||
.shaping(Shaping::Advanced)
|
||||
.font(font::MEDIUM)
|
||||
.size(P1_SIZE)
|
||||
}
|
||||
|
||||
pub fn p1_regular<'a>(content: impl Into<Cow<'a, str>>) -> iced::widget::Text<'a, Theme> {
|
||||
iced::widget::Text::new(content)
|
||||
pub fn p1_regular<'a>(content: impl Display) -> iced::widget::Text<'a, Theme> {
|
||||
iced::widget::text!("{}", content)
|
||||
.shaping(Shaping::Advanced)
|
||||
.font(font::REGULAR)
|
||||
.size(P1_SIZE)
|
||||
}
|
||||
|
||||
pub fn p2_medium<'a>(content: impl Into<Cow<'a, str>>) -> iced::widget::Text<'a, Theme> {
|
||||
iced::widget::Text::new(content)
|
||||
pub fn p2_medium<'a>(content: impl Display) -> iced::widget::Text<'a, Theme> {
|
||||
iced::widget::text!("{}", content)
|
||||
.shaping(Shaping::Advanced)
|
||||
.font(font::MEDIUM)
|
||||
.size(P2_SIZE)
|
||||
}
|
||||
|
||||
pub fn p2_regular<'a>(content: impl Into<Cow<'a, str>>) -> iced::widget::Text<'a, Theme> {
|
||||
iced::widget::Text::new(content)
|
||||
pub fn p2_regular<'a>(content: impl Display) -> iced::widget::Text<'a, Theme> {
|
||||
iced::widget::text!("{}", content)
|
||||
.shaping(Shaping::Advanced)
|
||||
.font(font::REGULAR)
|
||||
.size(P2_SIZE)
|
||||
}
|
||||
|
||||
pub fn caption<'a>(content: impl Into<Cow<'a, str>>) -> iced::widget::Text<'a, Theme> {
|
||||
iced::widget::Text::new(content)
|
||||
pub fn caption<'a>(content: impl Display) -> iced::widget::Text<'a, Theme> {
|
||||
iced::widget::text!("{}", content)
|
||||
.shaping(Shaping::Advanced)
|
||||
.font(font::REGULAR)
|
||||
.size(CAPTION_SIZE)
|
||||
}
|
||||
|
||||
pub fn text<'a>(content: impl Into<Cow<'a, str>>) -> iced::widget::Text<'a, Theme> {
|
||||
pub fn text<'a>(content: impl Display) -> iced::widget::Text<'a, Theme> {
|
||||
p1_regular(content)
|
||||
}
|
||||
|
||||
|
||||
@ -96,7 +96,7 @@ where
|
||||
state: &mut Tree,
|
||||
layout: Layout<'_>,
|
||||
renderer: &Renderer,
|
||||
operation: &mut dyn Operation<Message>,
|
||||
operation: &mut dyn Operation,
|
||||
) {
|
||||
operation.container(None, layout.bounds(), &mut |operation| {
|
||||
self.content
|
||||
@ -303,7 +303,7 @@ where
|
||||
&mut self,
|
||||
layout: Layout<'_>,
|
||||
renderer: &Renderer,
|
||||
operation: &mut dyn iced::advanced::widget::Operation<Message>,
|
||||
operation: &mut dyn iced::advanced::widget::Operation,
|
||||
) {
|
||||
operation.container(None, layout.bounds(), &mut |operation| {
|
||||
self.toasts
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
use crate::{icon, theme, widget::*};
|
||||
|
||||
pub fn tooltip<'a, T: 'a>(help: &'static str) -> Container<'a, T> {
|
||||
pub fn tooltip<T: 'static>(help: &'static str) -> Container<'static, T> {
|
||||
Container::new(
|
||||
iced::widget::tooltip::Tooltip::new(
|
||||
icon::tooltip_icon(),
|
||||
help,
|
||||
iced::widget::tooltip::Position::Right,
|
||||
)
|
||||
.style(theme::Container::Card(theme::Card::Simple)),
|
||||
.style(theme::card::simple),
|
||||
)
|
||||
}
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
use iced::{
|
||||
font::{Family, Stretch, Weight},
|
||||
Command, Font,
|
||||
Font,
|
||||
};
|
||||
use std::borrow::Cow;
|
||||
|
||||
pub const BOLD: Font = Font {
|
||||
family: Family::Name("IBM Plex Sans"),
|
||||
@ -26,12 +27,12 @@ pub const REGULAR_BYTES: &[u8] = include_bytes!("../static/fonts/IBMPlexSans-Reg
|
||||
pub const ICONEX_ICONS_BYTES: &[u8] = include_bytes!("../static/icons/iconex/iconex-icons.ttf");
|
||||
pub const BOOTSTRAP_ICONS_BYTE: &[u8] = include_bytes!("../static/icons/bootstrap-icons.ttf");
|
||||
|
||||
pub fn loads<T: From<Result<(), iced::font::Error>> + 'static>() -> Vec<Command<T>> {
|
||||
pub fn load() -> Vec<Cow<'static, [u8]>> {
|
||||
vec![
|
||||
iced::font::load(BOLD_BYTES).map(T::from),
|
||||
iced::font::load(MEDIUM_BYTES).map(T::from),
|
||||
iced::font::load(REGULAR_BYTES).map(T::from),
|
||||
iced::font::load(ICONEX_ICONS_BYTES).map(T::from),
|
||||
iced::font::load(BOOTSTRAP_ICONS_BYTE).map(T::from),
|
||||
BOLD_BYTES.into(),
|
||||
MEDIUM_BYTES.into(),
|
||||
REGULAR_BYTES.into(),
|
||||
ICONEX_ICONS_BYTES.into(),
|
||||
BOOTSTRAP_ICONS_BYTE.into(),
|
||||
]
|
||||
}
|
||||
|
||||
@ -7,7 +7,7 @@ fn bootstrap_icon(unicode: char) -> Text<'static> {
|
||||
Text::new(unicode.to_string())
|
||||
.font(BOOTSTRAP_ICONS)
|
||||
.width(Length::Fixed(20.0))
|
||||
.horizontal_alignment(alignment::Horizontal::Center)
|
||||
.align_x(alignment::Horizontal::Center)
|
||||
.size(P1_SIZE)
|
||||
}
|
||||
|
||||
@ -129,7 +129,7 @@ fn iconex_icon(unicode: char) -> Text<'static> {
|
||||
Text::new(unicode.to_string())
|
||||
.font(ICONEX_ICONS)
|
||||
.width(Length::Fixed(20.0))
|
||||
.horizontal_alignment(alignment::Horizontal::Center)
|
||||
.align_x(alignment::Horizontal::Center)
|
||||
.size(P1_SIZE)
|
||||
}
|
||||
|
||||
|
||||
@ -10,52 +10,52 @@ pub fn liana_app_icon() -> icon::Icon {
|
||||
icon::from_file_data(LIANA_APP_ICON, None).unwrap()
|
||||
}
|
||||
|
||||
pub fn liana_grey_logo() -> Svg {
|
||||
pub fn liana_grey_logo() -> Svg<'static> {
|
||||
let h = Handle::from_memory(LIANA_LOGO_GREY.to_vec());
|
||||
Svg::new(h)
|
||||
}
|
||||
|
||||
pub fn liana_brand_grey() -> Svg {
|
||||
pub fn liana_brand_grey() -> Svg<'static> {
|
||||
let h = Handle::from_memory(LIANA_BRAND_GREY.to_vec());
|
||||
Svg::new(h)
|
||||
}
|
||||
|
||||
pub fn wizardsardine() -> Svg {
|
||||
pub fn wizardsardine() -> Svg<'static> {
|
||||
let h = Handle::from_memory(WIZARDSARDINE_LETTERING.to_vec());
|
||||
Svg::new(h)
|
||||
}
|
||||
|
||||
const CREATE_NEW_WALLET_ICON: &[u8] = include_bytes!("../static/icons/blueprint.svg");
|
||||
|
||||
pub fn create_new_wallet_icon() -> Svg {
|
||||
pub fn create_new_wallet_icon() -> Svg<'static> {
|
||||
let h = Handle::from_memory(CREATE_NEW_WALLET_ICON.to_vec());
|
||||
Svg::new(h)
|
||||
}
|
||||
|
||||
const PARTICIPATE_IN_NEW_WALLET_ICON: &[u8] = include_bytes!("../static/icons/discussion.svg");
|
||||
|
||||
pub fn participate_in_new_wallet_icon() -> Svg {
|
||||
pub fn participate_in_new_wallet_icon() -> Svg<'static> {
|
||||
let h = Handle::from_memory(PARTICIPATE_IN_NEW_WALLET_ICON.to_vec());
|
||||
Svg::new(h)
|
||||
}
|
||||
|
||||
const RESTORE_WALLET_ICON: &[u8] = include_bytes!("../static/icons/syncdata.svg");
|
||||
|
||||
pub fn restore_wallet_icon() -> Svg {
|
||||
pub fn restore_wallet_icon() -> Svg<'static> {
|
||||
let h = Handle::from_memory(RESTORE_WALLET_ICON.to_vec());
|
||||
Svg::new(h)
|
||||
}
|
||||
|
||||
const SUCCESS_MARK_ICON: &[u8] = include_bytes!("../static/icons/success-mark.svg");
|
||||
|
||||
pub fn success_mark_icon() -> Svg {
|
||||
pub fn success_mark_icon() -> Svg<'static> {
|
||||
let h = Handle::from_memory(SUCCESS_MARK_ICON.to_vec());
|
||||
Svg::new(h)
|
||||
}
|
||||
|
||||
const KEY_MARK_ICON: &[u8] = include_bytes!("../static/icons/key-mark.svg");
|
||||
|
||||
pub fn key_mark_icon() -> Svg {
|
||||
pub fn key_mark_icon() -> Svg<'static> {
|
||||
let h = Handle::from_memory(KEY_MARK_ICON.to_vec());
|
||||
Svg::new(h)
|
||||
}
|
||||
@ -63,7 +63,7 @@ pub fn key_mark_icon() -> Svg {
|
||||
const INHERITANCE_TEMPLATE_DESC: &[u8] =
|
||||
include_bytes!("../static/images/inheritance_template_description.svg");
|
||||
|
||||
pub fn inheritance_template_description() -> Svg {
|
||||
pub fn inheritance_template_description() -> Svg<'static> {
|
||||
let h = Handle::from_memory(INHERITANCE_TEMPLATE_DESC.to_vec());
|
||||
Svg::new(h)
|
||||
}
|
||||
@ -71,7 +71,7 @@ pub fn inheritance_template_description() -> Svg {
|
||||
const CUSTOM_TEMPLATE_DESC: &[u8] =
|
||||
include_bytes!("../static/images/custom_template_description.svg");
|
||||
|
||||
pub fn custom_template_description() -> Svg {
|
||||
pub fn custom_template_description() -> Svg<'static> {
|
||||
let h = Handle::from_memory(CUSTOM_TEMPLATE_DESC.to_vec());
|
||||
Svg::new(h)
|
||||
}
|
||||
@ -79,7 +79,7 @@ pub fn custom_template_description() -> Svg {
|
||||
const MULTISIG_SECURITY_TEMPLATE_DESC: &[u8] =
|
||||
include_bytes!("../static/images/multisig_security_template.svg");
|
||||
|
||||
pub fn multisig_security_template_description() -> Svg {
|
||||
pub fn multisig_security_template_description() -> Svg<'static> {
|
||||
let h = Handle::from_memory(MULTISIG_SECURITY_TEMPLATE_DESC.to_vec());
|
||||
Svg::new(h)
|
||||
}
|
||||
|
||||
@ -19,9 +19,9 @@ pub mod widget {
|
||||
pub type Text<'a> = iced::widget::Text<'a, Theme, Renderer>;
|
||||
pub type TextInput<'a, Message> = iced::widget::TextInput<'a, Message, Theme, Renderer>;
|
||||
pub type Tooltip<'a> = iced::widget::Tooltip<'a, Theme, Renderer>;
|
||||
pub type ProgressBar = iced::widget::ProgressBar<Theme>;
|
||||
pub type ProgressBar<'a> = iced::widget::ProgressBar<'a, Theme>;
|
||||
pub type PickList<'a, T, L, V, Message> =
|
||||
iced::widget::PickList<'a, T, L, V, Message, Theme, Renderer>;
|
||||
pub type Scrollable<'a, Message> = iced::widget::Scrollable<'a, Message, Theme, Renderer>;
|
||||
pub type Svg = iced::widget::Svg<Theme>;
|
||||
pub type Svg<'a> = iced::widget::Svg<'a, Theme>;
|
||||
}
|
||||
|
||||
@ -1,990 +0,0 @@
|
||||
use iced::{
|
||||
application,
|
||||
widget::{
|
||||
button, checkbox, container, pick_list, progress_bar, qr_code, radio, scrollable, slider,
|
||||
svg, text, text_input,
|
||||
},
|
||||
};
|
||||
|
||||
use super::color;
|
||||
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq, Default)]
|
||||
pub enum Theme {
|
||||
#[default]
|
||||
Dark,
|
||||
Light,
|
||||
}
|
||||
|
||||
impl application::StyleSheet for Theme {
|
||||
type Style = ();
|
||||
|
||||
fn appearance(&self, _style: &Self::Style) -> application::Appearance {
|
||||
match self {
|
||||
Theme::Light => application::Appearance {
|
||||
background_color: color::GREY_2,
|
||||
text_color: color::LIGHT_BLACK,
|
||||
},
|
||||
Theme::Dark => application::Appearance {
|
||||
background_color: color::LIGHT_BLACK,
|
||||
text_color: color::WHITE,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Default)]
|
||||
pub enum Overlay {
|
||||
#[default]
|
||||
Default,
|
||||
}
|
||||
impl iced::overlay::menu::StyleSheet for Theme {
|
||||
type Style = Overlay;
|
||||
|
||||
fn appearance(&self, _style: &Self::Style) -> iced::overlay::menu::Appearance {
|
||||
iced::overlay::menu::Appearance {
|
||||
text_color: color::GREY_2,
|
||||
background: color::GREY_6.into(),
|
||||
border: iced::Border {
|
||||
color: color::GREY_2,
|
||||
width: 0.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
selected_text_color: color::LIGHT_BLACK,
|
||||
selected_background: color::GREEN.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl From<PickList> for Overlay {
|
||||
fn from(_p: PickList) -> Overlay {
|
||||
Overlay::Default
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Default)]
|
||||
pub enum Text {
|
||||
#[default]
|
||||
Default,
|
||||
Color(iced::Color),
|
||||
}
|
||||
|
||||
impl From<iced::Color> for Text {
|
||||
fn from(color: iced::Color) -> Self {
|
||||
Text::Color(color)
|
||||
}
|
||||
}
|
||||
|
||||
impl text::StyleSheet for Theme {
|
||||
type Style = Text;
|
||||
|
||||
fn appearance(&self, style: Self::Style) -> text::Appearance {
|
||||
match style {
|
||||
Text::Default => Default::default(),
|
||||
Text::Color(c) => text::Appearance { color: Some(c) },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, Default)]
|
||||
pub enum Container {
|
||||
#[default]
|
||||
Transparent,
|
||||
Background,
|
||||
Foreground,
|
||||
Border,
|
||||
Banner,
|
||||
Card(Card),
|
||||
Badge(Badge),
|
||||
Pill(Pill),
|
||||
Custom(iced::Color),
|
||||
Notification(Notification),
|
||||
QrCode,
|
||||
}
|
||||
|
||||
impl container::StyleSheet for Theme {
|
||||
type Style = Container;
|
||||
fn appearance(&self, style: &Self::Style) -> iced::widget::container::Appearance {
|
||||
match self {
|
||||
Theme::Light => match style {
|
||||
Container::Transparent => container::Appearance {
|
||||
background: Some(iced::Color::TRANSPARENT.into()),
|
||||
..container::Appearance::default()
|
||||
},
|
||||
Container::Background => container::Appearance {
|
||||
background: Some(color::GREY_2.into()),
|
||||
..container::Appearance::default()
|
||||
},
|
||||
Container::Foreground => container::Appearance {
|
||||
background: Some(color::GREY_2.into()),
|
||||
..container::Appearance::default()
|
||||
},
|
||||
Container::Border => container::Appearance {
|
||||
background: Some(iced::Color::TRANSPARENT.into()),
|
||||
border: iced::Border {
|
||||
color: color::LIGHT_BLACK,
|
||||
width: 1.0,
|
||||
radius: 0.0.into(),
|
||||
},
|
||||
..container::Appearance::default()
|
||||
},
|
||||
Container::Card(c) => c.appearance(self),
|
||||
Container::Badge(c) => c.appearance(self),
|
||||
Container::Pill(c) => c.appearance(self),
|
||||
Container::Notification(c) => c.appearance(self),
|
||||
Container::Custom(c) => container::Appearance {
|
||||
background: Some((*c).into()),
|
||||
..container::Appearance::default()
|
||||
},
|
||||
Container::QrCode => container::Appearance {
|
||||
background: Some(color::WHITE.into()),
|
||||
border: iced::Border {
|
||||
color: color::TRANSPARENT,
|
||||
width: 0.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
..container::Appearance::default()
|
||||
},
|
||||
Container::Banner => container::Appearance {
|
||||
background: Some(color::WHITE.into()),
|
||||
border: iced::Border {
|
||||
color: color::TRANSPARENT,
|
||||
width: 0.0,
|
||||
radius: 0.0.into(),
|
||||
},
|
||||
text_color: color::LIGHT_BLACK.into(),
|
||||
..container::Appearance::default()
|
||||
},
|
||||
},
|
||||
Theme::Dark => match style {
|
||||
Container::Transparent => container::Appearance {
|
||||
background: Some(iced::Color::TRANSPARENT.into()),
|
||||
..container::Appearance::default()
|
||||
},
|
||||
Container::Background => container::Appearance {
|
||||
background: Some(color::LIGHT_BLACK.into()),
|
||||
..container::Appearance::default()
|
||||
},
|
||||
Container::Foreground => container::Appearance {
|
||||
background: Some(color::BLACK.into()),
|
||||
..container::Appearance::default()
|
||||
},
|
||||
Container::Border => container::Appearance {
|
||||
background: Some(iced::Color::TRANSPARENT.into()),
|
||||
border: iced::Border {
|
||||
color: color::GREY_3,
|
||||
width: 1.0,
|
||||
radius: 0.0.into(),
|
||||
},
|
||||
..container::Appearance::default()
|
||||
},
|
||||
Container::Card(c) => c.appearance(self),
|
||||
Container::Badge(c) => c.appearance(self),
|
||||
Container::Pill(c) => c.appearance(self),
|
||||
Container::Notification(c) => c.appearance(self),
|
||||
Container::Custom(c) => container::Appearance {
|
||||
background: Some((*c).into()),
|
||||
..container::Appearance::default()
|
||||
},
|
||||
Container::QrCode => container::Appearance {
|
||||
background: Some(color::WHITE.into()),
|
||||
border: iced::Border {
|
||||
color: color::TRANSPARENT,
|
||||
width: 0.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
..container::Appearance::default()
|
||||
},
|
||||
Container::Banner => container::Appearance {
|
||||
background: Some(color::BLUE.into()),
|
||||
border: iced::Border {
|
||||
color: color::TRANSPARENT,
|
||||
width: 0.0,
|
||||
radius: 0.0.into(),
|
||||
},
|
||||
text_color: color::LIGHT_BLACK.into(),
|
||||
..container::Appearance::default()
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Card> for Container {
|
||||
fn from(c: Card) -> Container {
|
||||
Container::Card(c)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Badge> for Container {
|
||||
fn from(c: Badge) -> Container {
|
||||
Container::Badge(c)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Pill> for Container {
|
||||
fn from(c: Pill) -> Container {
|
||||
Container::Pill(c)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, Default)]
|
||||
pub enum Notification {
|
||||
#[default]
|
||||
Pending,
|
||||
Error,
|
||||
}
|
||||
|
||||
impl Notification {
|
||||
fn appearance(&self, theme: &Theme) -> iced::widget::container::Appearance {
|
||||
match theme {
|
||||
Theme::Light => match self {
|
||||
Self::Pending => container::Appearance {
|
||||
background: Some(iced::Background::Color(color::GREEN)),
|
||||
text_color: color::LIGHT_BLACK.into(),
|
||||
border: iced::Border {
|
||||
color: color::GREEN,
|
||||
width: 1.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
..container::Appearance::default()
|
||||
},
|
||||
Self::Error => container::Appearance {
|
||||
background: Some(iced::Background::Color(color::ORANGE)),
|
||||
text_color: color::LIGHT_BLACK.into(),
|
||||
border: iced::Border {
|
||||
color: color::ORANGE,
|
||||
width: 1.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
..container::Appearance::default()
|
||||
},
|
||||
},
|
||||
Theme::Dark => match self {
|
||||
Self::Pending => container::Appearance {
|
||||
background: Some(iced::Background::Color(color::GREEN)),
|
||||
text_color: color::LIGHT_BLACK.into(),
|
||||
border: iced::Border {
|
||||
color: color::GREEN,
|
||||
width: 1.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
..container::Appearance::default()
|
||||
},
|
||||
Self::Error => container::Appearance {
|
||||
background: Some(iced::Background::Color(color::ORANGE)),
|
||||
text_color: color::LIGHT_BLACK.into(),
|
||||
border: iced::Border {
|
||||
color: color::ORANGE,
|
||||
width: 1.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
..container::Appearance::default()
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, Default)]
|
||||
pub enum Card {
|
||||
#[default]
|
||||
Simple,
|
||||
Modal,
|
||||
Border,
|
||||
Invalid,
|
||||
Warning,
|
||||
Error,
|
||||
}
|
||||
|
||||
impl Card {
|
||||
fn appearance(&self, theme: &Theme) -> iced::widget::container::Appearance {
|
||||
match theme {
|
||||
Theme::Light => match self {
|
||||
Card::Simple => container::Appearance {
|
||||
background: Some(color::GREY_2.into()),
|
||||
..container::Appearance::default()
|
||||
},
|
||||
Card::Modal => container::Appearance {
|
||||
background: Some(color::GREY_2.into()),
|
||||
..container::Appearance::default()
|
||||
},
|
||||
Card::Border => container::Appearance {
|
||||
background: Some(iced::Color::TRANSPARENT.into()),
|
||||
border: iced::Border {
|
||||
color: color::GREY_7,
|
||||
width: 1.0,
|
||||
radius: 10.0.into(),
|
||||
},
|
||||
..container::Appearance::default()
|
||||
},
|
||||
Card::Invalid => container::Appearance {
|
||||
background: Some(color::GREY_2.into()),
|
||||
text_color: color::BLACK.into(),
|
||||
border: iced::Border {
|
||||
color: color::RED,
|
||||
width: 1.0,
|
||||
radius: 0.0.into(),
|
||||
},
|
||||
..container::Appearance::default()
|
||||
},
|
||||
Card::Error => container::Appearance {
|
||||
background: Some(color::GREY_2.into()),
|
||||
text_color: color::RED.into(),
|
||||
border: iced::Border {
|
||||
color: color::RED,
|
||||
width: 1.0,
|
||||
radius: 0.0.into(),
|
||||
},
|
||||
..container::Appearance::default()
|
||||
},
|
||||
Card::Warning => container::Appearance {
|
||||
background: Some(color::ORANGE.into()),
|
||||
text_color: color::GREY_2.into(),
|
||||
..container::Appearance::default()
|
||||
},
|
||||
},
|
||||
Theme::Dark => match self {
|
||||
Card::Simple => container::Appearance {
|
||||
background: Some(color::GREY_6.into()),
|
||||
border: iced::Border {
|
||||
color: color::TRANSPARENT,
|
||||
width: 0.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
..container::Appearance::default()
|
||||
},
|
||||
Card::Modal => container::Appearance {
|
||||
background: Some(color::LIGHT_BLACK.into()),
|
||||
border: iced::Border {
|
||||
color: color::TRANSPARENT,
|
||||
width: 0.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
..container::Appearance::default()
|
||||
},
|
||||
Card::Border => container::Appearance {
|
||||
background: Some(iced::Color::TRANSPARENT.into()),
|
||||
border: iced::Border {
|
||||
color: color::GREY_7,
|
||||
width: 1.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
..container::Appearance::default()
|
||||
},
|
||||
Card::Invalid => container::Appearance {
|
||||
background: Some(color::LIGHT_BLACK.into()),
|
||||
text_color: color::RED.into(),
|
||||
border: iced::Border {
|
||||
color: color::RED,
|
||||
width: 1.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
..container::Appearance::default()
|
||||
},
|
||||
Card::Error => container::Appearance {
|
||||
background: Some(color::LIGHT_BLACK.into()),
|
||||
text_color: color::RED.into(),
|
||||
border: iced::Border {
|
||||
color: color::RED,
|
||||
width: 1.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
..container::Appearance::default()
|
||||
},
|
||||
Card::Warning => container::Appearance {
|
||||
background: Some(color::ORANGE.into()),
|
||||
text_color: color::LIGHT_BLACK.into(),
|
||||
..container::Appearance::default()
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, Default)]
|
||||
pub enum Badge {
|
||||
#[default]
|
||||
Standard,
|
||||
Bitcoin,
|
||||
}
|
||||
|
||||
impl Badge {
|
||||
fn appearance(&self, _theme: &Theme) -> iced::widget::container::Appearance {
|
||||
match self {
|
||||
Self::Standard => container::Appearance {
|
||||
border: iced::Border {
|
||||
color: color::TRANSPARENT,
|
||||
width: 0.0,
|
||||
radius: 40.0.into(),
|
||||
},
|
||||
background: Some(color::GREY_4.into()),
|
||||
..container::Appearance::default()
|
||||
},
|
||||
Self::Bitcoin => container::Appearance {
|
||||
border: iced::Border {
|
||||
color: color::TRANSPARENT,
|
||||
width: 0.0,
|
||||
radius: 40.0.into(),
|
||||
},
|
||||
background: Some(color::ORANGE.into()),
|
||||
text_color: iced::Color::WHITE.into(),
|
||||
..container::Appearance::default()
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, Default)]
|
||||
pub enum Pill {
|
||||
#[default]
|
||||
Simple,
|
||||
Primary,
|
||||
Success,
|
||||
Warning,
|
||||
}
|
||||
|
||||
impl Pill {
|
||||
fn appearance(&self, _theme: &Theme) -> iced::widget::container::Appearance {
|
||||
match self {
|
||||
Self::Primary => container::Appearance {
|
||||
background: Some(color::GREEN.into()),
|
||||
border: iced::Border {
|
||||
color: color::TRANSPARENT,
|
||||
width: 0.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
text_color: color::LIGHT_BLACK.into(),
|
||||
..container::Appearance::default()
|
||||
},
|
||||
Self::Success => container::Appearance {
|
||||
background: Some(color::GREEN.into()),
|
||||
border: iced::Border {
|
||||
color: color::TRANSPARENT,
|
||||
width: 0.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
text_color: color::LIGHT_BLACK.into(),
|
||||
..container::Appearance::default()
|
||||
},
|
||||
Self::Simple => container::Appearance {
|
||||
background: Some(iced::Color::TRANSPARENT.into()),
|
||||
border: iced::Border {
|
||||
color: color::GREY_3,
|
||||
width: 1.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
text_color: color::GREY_3.into(),
|
||||
..container::Appearance::default()
|
||||
},
|
||||
Self::Warning => container::Appearance {
|
||||
background: Some(iced::Color::TRANSPARENT.into()),
|
||||
border: iced::Border {
|
||||
color: color::RED,
|
||||
width: 1.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
text_color: color::RED.into(),
|
||||
..container::Appearance::default()
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Radio {}
|
||||
impl radio::StyleSheet for Theme {
|
||||
type Style = Radio;
|
||||
|
||||
fn active(&self, _style: &Self::Style, _is_selected: bool) -> radio::Appearance {
|
||||
radio::Appearance {
|
||||
background: iced::Color::TRANSPARENT.into(),
|
||||
dot_color: color::GREEN,
|
||||
border_width: 1.0,
|
||||
border_color: color::GREY_7,
|
||||
text_color: None,
|
||||
}
|
||||
}
|
||||
|
||||
fn hovered(&self, style: &Self::Style, is_selected: bool) -> radio::Appearance {
|
||||
let active = self.active(style, is_selected);
|
||||
radio::Appearance {
|
||||
dot_color: color::GREEN,
|
||||
border_color: color::GREEN,
|
||||
background: iced::Color::TRANSPARENT.into(),
|
||||
..active
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Clone)]
|
||||
pub struct Scrollable {}
|
||||
impl scrollable::StyleSheet for Theme {
|
||||
type Style = Scrollable;
|
||||
|
||||
fn active(&self, _style: &Self::Style) -> scrollable::Appearance {
|
||||
scrollable::Appearance {
|
||||
gap: None,
|
||||
container: container::Appearance::default(),
|
||||
scrollbar: scrollable::Scrollbar {
|
||||
background: None,
|
||||
border: iced::Border {
|
||||
color: color::GREY_3,
|
||||
width: 0.0,
|
||||
radius: 10.0.into(),
|
||||
},
|
||||
scroller: scrollable::Scroller {
|
||||
color: color::GREY_7,
|
||||
border: iced::Border {
|
||||
color: color::TRANSPARENT,
|
||||
width: 0.0,
|
||||
radius: 10.0.into(),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn hovered(&self, style: &Self::Style, _is_hovered: bool) -> scrollable::Appearance {
|
||||
let active = self.active(style);
|
||||
scrollable::Appearance { ..active }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Clone)]
|
||||
pub enum PickList {
|
||||
#[default]
|
||||
Secondary,
|
||||
}
|
||||
impl pick_list::StyleSheet for Theme {
|
||||
type Style = PickList;
|
||||
|
||||
fn active(&self, _style: &Self::Style) -> pick_list::Appearance {
|
||||
pick_list::Appearance {
|
||||
placeholder_color: color::GREY_6,
|
||||
handle_color: color::GREY_7,
|
||||
background: color::GREY_6.into(),
|
||||
border: iced::Border {
|
||||
color: color::GREY_7,
|
||||
width: 1.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
text_color: color::GREY_2,
|
||||
}
|
||||
}
|
||||
|
||||
fn hovered(&self, _style: &Self::Style) -> pick_list::Appearance {
|
||||
pick_list::Appearance {
|
||||
placeholder_color: color::GREY_6,
|
||||
handle_color: color::GREEN,
|
||||
background: color::GREY_6.into(),
|
||||
border: iced::Border {
|
||||
color: color::GREEN,
|
||||
width: 1.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
text_color: color::GREEN,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct CheckBox {}
|
||||
impl checkbox::StyleSheet for Theme {
|
||||
type Style = CheckBox;
|
||||
|
||||
fn active(&self, _style: &Self::Style, is_selected: bool) -> checkbox::Appearance {
|
||||
if is_selected {
|
||||
checkbox::Appearance {
|
||||
background: color::GREEN.into(),
|
||||
icon_color: color::GREY_4,
|
||||
text_color: None,
|
||||
border: iced::Border {
|
||||
color: color::TRANSPARENT,
|
||||
width: 1.0,
|
||||
radius: 4.0.into(),
|
||||
},
|
||||
}
|
||||
} else {
|
||||
checkbox::Appearance {
|
||||
background: color::GREY_4.into(),
|
||||
icon_color: color::GREEN,
|
||||
text_color: None,
|
||||
border: iced::Border {
|
||||
color: color::TRANSPARENT,
|
||||
width: 0.0,
|
||||
radius: 4.0.into(),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn hovered(&self, style: &Self::Style, is_selected: bool) -> checkbox::Appearance {
|
||||
self.active(style, is_selected)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub enum Button {
|
||||
#[default]
|
||||
Primary,
|
||||
Secondary,
|
||||
Destructive,
|
||||
SecondaryDestructive,
|
||||
Transparent,
|
||||
TransparentBorder,
|
||||
Border,
|
||||
Menu(bool),
|
||||
}
|
||||
|
||||
impl button::StyleSheet for Theme {
|
||||
type Style = Button;
|
||||
|
||||
fn active(&self, style: &Self::Style) -> button::Appearance {
|
||||
match self {
|
||||
Theme::Light => button::Appearance::default(),
|
||||
Theme::Dark => match style {
|
||||
Button::Primary => button::Appearance {
|
||||
shadow_offset: iced::Vector::default(),
|
||||
background: Some(color::GREEN.into()),
|
||||
text_color: color::LIGHT_BLACK,
|
||||
border: iced::Border {
|
||||
color: color::GREEN,
|
||||
width: 1.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
..button::Appearance::default()
|
||||
},
|
||||
Button::Secondary | Button::SecondaryDestructive | Button::Border => {
|
||||
button::Appearance {
|
||||
shadow_offset: iced::Vector::default(),
|
||||
background: Some(color::GREY_6.into()),
|
||||
text_color: color::GREY_2,
|
||||
border: iced::Border {
|
||||
color: color::GREY_7,
|
||||
width: 1.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
..button::Appearance::default()
|
||||
}
|
||||
}
|
||||
Button::Destructive => button::Appearance {
|
||||
shadow_offset: iced::Vector::default(),
|
||||
background: Some(color::GREY_6.into()),
|
||||
text_color: color::RED,
|
||||
border: iced::Border {
|
||||
color: color::RED,
|
||||
width: 1.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
..button::Appearance::default()
|
||||
},
|
||||
Button::Transparent => button::Appearance {
|
||||
shadow_offset: iced::Vector::default(),
|
||||
background: Some(iced::Color::TRANSPARENT.into()),
|
||||
text_color: color::GREY_2,
|
||||
border: iced::Border {
|
||||
color: color::TRANSPARENT,
|
||||
width: 0.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
..button::Appearance::default()
|
||||
},
|
||||
Button::TransparentBorder => button::Appearance {
|
||||
shadow_offset: iced::Vector::default(),
|
||||
background: Some(iced::Color::TRANSPARENT.into()),
|
||||
text_color: color::WHITE,
|
||||
border: iced::Border {
|
||||
color: color::TRANSPARENT,
|
||||
width: 0.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
..button::Appearance::default()
|
||||
},
|
||||
Button::Menu(active) => {
|
||||
if *active {
|
||||
button::Appearance {
|
||||
shadow_offset: iced::Vector::default(),
|
||||
background: Some(color::LIGHT_BLACK.into()),
|
||||
text_color: color::WHITE,
|
||||
border: iced::Border {
|
||||
color: color::TRANSPARENT,
|
||||
width: 0.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
..button::Appearance::default()
|
||||
}
|
||||
} else {
|
||||
button::Appearance {
|
||||
shadow_offset: iced::Vector::default(),
|
||||
background: Some(iced::Color::TRANSPARENT.into()),
|
||||
text_color: color::WHITE,
|
||||
border: iced::Border {
|
||||
color: color::TRANSPARENT,
|
||||
width: 0.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
..button::Appearance::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn hovered(&self, style: &Self::Style) -> button::Appearance {
|
||||
match self {
|
||||
Theme::Light => button::Appearance::default(),
|
||||
Theme::Dark => match style {
|
||||
Button::Primary => button::Appearance {
|
||||
shadow_offset: iced::Vector::default(),
|
||||
background: Some(color::GREEN.into()),
|
||||
text_color: color::LIGHT_BLACK,
|
||||
border: iced::Border {
|
||||
color: color::TRANSPARENT,
|
||||
width: 0.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
..button::Appearance::default()
|
||||
},
|
||||
Button::Secondary => button::Appearance {
|
||||
shadow_offset: iced::Vector::default(),
|
||||
background: Some(color::GREY_6.into()),
|
||||
text_color: color::GREEN,
|
||||
border: iced::Border {
|
||||
color: color::GREEN,
|
||||
width: 1.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
..button::Appearance::default()
|
||||
},
|
||||
Button::Destructive | Button::SecondaryDestructive => button::Appearance {
|
||||
shadow_offset: iced::Vector::default(),
|
||||
background: Some(color::RED.into()),
|
||||
text_color: color::LIGHT_BLACK,
|
||||
border: iced::Border {
|
||||
color: color::TRANSPARENT,
|
||||
width: 0.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
..button::Appearance::default()
|
||||
},
|
||||
Button::Transparent => button::Appearance {
|
||||
shadow_offset: iced::Vector::default(),
|
||||
background: Some(iced::Color::TRANSPARENT.into()),
|
||||
text_color: color::GREY_2,
|
||||
border: iced::Border {
|
||||
color: color::TRANSPARENT,
|
||||
width: 0.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
..button::Appearance::default()
|
||||
},
|
||||
Button::TransparentBorder | Button::Border => button::Appearance {
|
||||
shadow_offset: iced::Vector::default(),
|
||||
background: Some(color::GREY_6.into()),
|
||||
text_color: color::WHITE,
|
||||
border: iced::Border {
|
||||
color: color::GREEN,
|
||||
width: 1.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
..button::Appearance::default()
|
||||
},
|
||||
Button::Menu(_) => button::Appearance {
|
||||
shadow_offset: iced::Vector::default(),
|
||||
background: Some(color::LIGHT_BLACK.into()),
|
||||
text_color: color::WHITE,
|
||||
border: iced::Border {
|
||||
color: color::TRANSPARENT,
|
||||
width: 0.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
..button::Appearance::default()
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
fn disabled(&self, style: &Self::Style) -> button::Appearance {
|
||||
let active = if let Button::Primary = style {
|
||||
self.active(&Button::Secondary)
|
||||
} else {
|
||||
self.active(style)
|
||||
};
|
||||
button::Appearance {
|
||||
shadow_offset: iced::Vector::default(),
|
||||
background: Some(color::TRANSPARENT.into()),
|
||||
text_color: iced::Color {
|
||||
a: active.text_color.a * 0.5,
|
||||
..active.text_color
|
||||
},
|
||||
..active
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, Default)]
|
||||
pub enum Form {
|
||||
#[default]
|
||||
Simple,
|
||||
Invalid,
|
||||
}
|
||||
|
||||
impl text_input::StyleSheet for Theme {
|
||||
type Style = Form;
|
||||
fn active(&self, style: &Self::Style) -> text_input::Appearance {
|
||||
match style {
|
||||
Form::Simple => text_input::Appearance {
|
||||
icon_color: color::GREY_7,
|
||||
background: iced::Background::Color(iced::Color::TRANSPARENT),
|
||||
border: iced::Border {
|
||||
color: color::GREY_7,
|
||||
width: 1.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
},
|
||||
Form::Invalid => text_input::Appearance {
|
||||
icon_color: color::GREY_7,
|
||||
background: iced::Background::Color(iced::Color::TRANSPARENT),
|
||||
border: iced::Border {
|
||||
color: color::RED,
|
||||
width: 1.0,
|
||||
radius: 25.0.into(),
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn disabled(&self, style: &Self::Style) -> text_input::Appearance {
|
||||
text_input::Appearance {
|
||||
..self.active(style)
|
||||
}
|
||||
}
|
||||
|
||||
fn focused(&self, style: &Self::Style) -> text_input::Appearance {
|
||||
text_input::Appearance {
|
||||
..self.active(style)
|
||||
}
|
||||
}
|
||||
|
||||
fn disabled_color(&self, _style: &Self::Style) -> iced::Color {
|
||||
color::GREY_7
|
||||
}
|
||||
|
||||
fn placeholder_color(&self, _style: &Self::Style) -> iced::Color {
|
||||
color::GREY_7
|
||||
}
|
||||
|
||||
fn value_color(&self, _style: &Self::Style) -> iced::Color {
|
||||
color::GREY_2
|
||||
}
|
||||
|
||||
fn selection_color(&self, _style: &Self::Style) -> iced::Color {
|
||||
color::GREEN
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, Default)]
|
||||
pub enum ProgressBar {
|
||||
#[default]
|
||||
Simple,
|
||||
}
|
||||
|
||||
impl progress_bar::StyleSheet for Theme {
|
||||
type Style = ProgressBar;
|
||||
fn appearance(&self, _style: &Self::Style) -> progress_bar::Appearance {
|
||||
progress_bar::Appearance {
|
||||
background: color::GREY_6.into(),
|
||||
bar: color::GREEN.into(),
|
||||
border_radius: 10.0.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, Default)]
|
||||
pub enum Slider {
|
||||
#[default]
|
||||
Simple,
|
||||
}
|
||||
|
||||
impl slider::StyleSheet for Theme {
|
||||
type Style = Slider;
|
||||
fn active(&self, _style: &Self::Style) -> slider::Appearance {
|
||||
let handle = slider::Handle {
|
||||
shape: slider::HandleShape::Rectangle {
|
||||
width: 8,
|
||||
border_radius: 4.0.into(),
|
||||
},
|
||||
color: color::BLACK,
|
||||
border_color: color::GREEN,
|
||||
border_width: 1.0,
|
||||
};
|
||||
slider::Appearance {
|
||||
rail: slider::Rail {
|
||||
colors: (color::GREEN, iced::Color::TRANSPARENT),
|
||||
border_radius: 4.0.into(),
|
||||
width: 2.0,
|
||||
},
|
||||
handle,
|
||||
}
|
||||
}
|
||||
fn hovered(&self, _style: &Self::Style) -> slider::Appearance {
|
||||
let handle = slider::Handle {
|
||||
shape: slider::HandleShape::Rectangle {
|
||||
width: 8,
|
||||
border_radius: 4.0.into(),
|
||||
},
|
||||
color: color::GREEN,
|
||||
border_color: color::GREEN,
|
||||
border_width: 1.0,
|
||||
};
|
||||
slider::Appearance {
|
||||
rail: slider::Rail {
|
||||
colors: (color::GREEN, iced::Color::TRANSPARENT),
|
||||
border_radius: 4.0.into(),
|
||||
width: 2.0,
|
||||
},
|
||||
handle,
|
||||
}
|
||||
}
|
||||
fn dragging(&self, _style: &Self::Style) -> slider::Appearance {
|
||||
let handle = slider::Handle {
|
||||
shape: slider::HandleShape::Rectangle {
|
||||
width: 8,
|
||||
border_radius: 4.0.into(),
|
||||
},
|
||||
color: color::GREEN,
|
||||
border_color: color::GREEN,
|
||||
border_width: 1.0,
|
||||
};
|
||||
slider::Appearance {
|
||||
rail: slider::Rail {
|
||||
colors: (color::GREEN, iced::Color::TRANSPARENT),
|
||||
border_radius: 4.0.into(),
|
||||
width: 2.0,
|
||||
},
|
||||
handle,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, Default)]
|
||||
pub enum Svg {
|
||||
#[default]
|
||||
Simple,
|
||||
}
|
||||
|
||||
impl svg::StyleSheet for Theme {
|
||||
type Style = ProgressBar;
|
||||
fn appearance(&self, _style: &Self::Style) -> svg::Appearance {
|
||||
svg::Appearance::default()
|
||||
}
|
||||
}
|
||||
|
||||
impl qr_code::StyleSheet for Theme {
|
||||
type Style = ();
|
||||
fn appearance(&self, _style: &Self::Style) -> qr_code::Appearance {
|
||||
qr_code::Appearance {
|
||||
cell: color::BLACK,
|
||||
background: color::WHITE,
|
||||
}
|
||||
}
|
||||
}
|
||||
26
liana-ui/src/theme/badge.rs
Normal file
26
liana-ui/src/theme/badge.rs
Normal file
@ -0,0 +1,26 @@
|
||||
use iced::widget::container::Style;
|
||||
use iced::{Background, Border};
|
||||
|
||||
use super::palette::ContainerPalette;
|
||||
use super::Theme;
|
||||
|
||||
fn badge(palette: &ContainerPalette) -> Style {
|
||||
Style {
|
||||
background: Some(Background::Color(palette.background)),
|
||||
text_color: palette.text,
|
||||
border: Border {
|
||||
radius: 25.0.into(),
|
||||
width: 1.0,
|
||||
color: iced::Color::TRANSPARENT,
|
||||
},
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn simple(theme: &Theme) -> Style {
|
||||
badge(&theme.colors.badges.simple)
|
||||
}
|
||||
|
||||
pub fn bitcoin(theme: &Theme) -> Style {
|
||||
badge(&theme.colors.badges.bitcoin)
|
||||
}
|
||||
28
liana-ui/src/theme/banner.rs
Normal file
28
liana-ui/src/theme/banner.rs
Normal file
@ -0,0 +1,28 @@
|
||||
use iced::widget::container::Style;
|
||||
use iced::{Background, Border};
|
||||
|
||||
use super::palette::ContainerPalette;
|
||||
use super::Theme;
|
||||
|
||||
fn banner(palette: &ContainerPalette) -> Style {
|
||||
Style {
|
||||
background: Some(Background::Color(palette.background)),
|
||||
text_color: palette.text,
|
||||
border: if let Some(color) = palette.border {
|
||||
Border {
|
||||
width: 1.0,
|
||||
color,
|
||||
..Default::default()
|
||||
}
|
||||
} else {
|
||||
Border {
|
||||
..Default::default()
|
||||
}
|
||||
},
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn network(theme: &Theme) -> Style {
|
||||
banner(&theme.colors.banners.network)
|
||||
}
|
||||
147
liana-ui/src/theme/button.rs
Normal file
147
liana-ui/src/theme/button.rs
Normal file
@ -0,0 +1,147 @@
|
||||
use iced::widget::button::{Catalog, Status, Style, StyleFn};
|
||||
use iced::{Background, Border, Color};
|
||||
|
||||
use super::palette::Button;
|
||||
use super::Theme;
|
||||
|
||||
impl Catalog for Theme {
|
||||
type Class<'a> = StyleFn<'a, Self>;
|
||||
|
||||
fn default<'a>() -> Self::Class<'a> {
|
||||
Box::new(primary)
|
||||
}
|
||||
|
||||
fn style(&self, class: &Self::Class<'_>, status: Status) -> Style {
|
||||
class(self, status)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn primary(theme: &Theme, status: Status) -> Style {
|
||||
button(&theme.colors.buttons.primary, status)
|
||||
}
|
||||
|
||||
pub fn secondary(theme: &Theme, status: Status) -> Style {
|
||||
button(&theme.colors.buttons.secondary, status)
|
||||
}
|
||||
|
||||
pub fn destructive(theme: &Theme, status: Status) -> Style {
|
||||
button(&theme.colors.buttons.destructive, status)
|
||||
}
|
||||
|
||||
pub fn container(theme: &Theme, status: Status) -> Style {
|
||||
button(&theme.colors.buttons.container, status)
|
||||
}
|
||||
|
||||
pub fn container_border(theme: &Theme, status: Status) -> Style {
|
||||
button(&theme.colors.buttons.container_border, status)
|
||||
}
|
||||
|
||||
pub fn menu(theme: &Theme, status: Status) -> Style {
|
||||
button(&theme.colors.buttons.menu, status)
|
||||
}
|
||||
|
||||
pub fn menu_pressed(theme: &Theme, _status: Status) -> Style {
|
||||
button(&theme.colors.buttons.menu, Status::Pressed)
|
||||
}
|
||||
|
||||
pub fn transparent(theme: &Theme, status: Status) -> Style {
|
||||
button(&theme.colors.buttons.transparent, status)
|
||||
}
|
||||
|
||||
pub fn transparent_border(theme: &Theme, status: Status) -> Style {
|
||||
button(&theme.colors.buttons.transparent_border, status)
|
||||
}
|
||||
|
||||
fn button(p: &Button, status: Status) -> Style {
|
||||
match status {
|
||||
Status::Active => Style {
|
||||
background: Some(Background::Color(p.active.background)),
|
||||
text_color: p.active.text,
|
||||
border: if let Some(color) = p.active.border {
|
||||
Border {
|
||||
radius: 25.0.into(),
|
||||
width: 1.0,
|
||||
color,
|
||||
}
|
||||
} else {
|
||||
Border {
|
||||
..Default::default()
|
||||
}
|
||||
},
|
||||
..Default::default()
|
||||
},
|
||||
Status::Pressed => {
|
||||
if let Some(pressed) = p.pressed {
|
||||
Style {
|
||||
background: Some(Background::Color(pressed.background)),
|
||||
text_color: pressed.text,
|
||||
border: if let Some(color) = pressed.border {
|
||||
Border {
|
||||
radius: 25.0.into(),
|
||||
width: 1.0,
|
||||
color,
|
||||
}
|
||||
} else {
|
||||
Border {
|
||||
..Default::default()
|
||||
}
|
||||
},
|
||||
..Default::default()
|
||||
}
|
||||
} else {
|
||||
button(p, Status::Active)
|
||||
}
|
||||
}
|
||||
Status::Hovered => Style {
|
||||
background: Some(Background::Color(p.hovered.background)),
|
||||
text_color: p.hovered.text,
|
||||
border: if let Some(color) = p.hovered.border {
|
||||
Border {
|
||||
radius: 25.0.into(),
|
||||
width: 1.0,
|
||||
color,
|
||||
}
|
||||
} else {
|
||||
Border {
|
||||
..Default::default()
|
||||
}
|
||||
},
|
||||
..Default::default()
|
||||
},
|
||||
Status::Disabled => {
|
||||
if let Some(disabled) = p.disabled {
|
||||
Style {
|
||||
background: Some(Background::Color(disabled.background)),
|
||||
text_color: Color {
|
||||
a: 0.2,
|
||||
r: disabled.text.r,
|
||||
g: disabled.text.g,
|
||||
b: disabled.text.b,
|
||||
},
|
||||
border: if let Some(color) = disabled.border {
|
||||
Border {
|
||||
radius: 25.0.into(),
|
||||
width: 1.0,
|
||||
color,
|
||||
}
|
||||
} else {
|
||||
Border {
|
||||
..Default::default()
|
||||
}
|
||||
},
|
||||
..Default::default()
|
||||
}
|
||||
} else {
|
||||
let active: Style = button(p, Status::Active);
|
||||
|
||||
Style {
|
||||
text_color: Color {
|
||||
a: 0.2,
|
||||
..active.text_color
|
||||
},
|
||||
..active
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
48
liana-ui/src/theme/card.rs
Normal file
48
liana-ui/src/theme/card.rs
Normal file
@ -0,0 +1,48 @@
|
||||
use iced::widget::container::Style;
|
||||
use iced::{Background, Border};
|
||||
|
||||
use super::palette::ContainerPalette;
|
||||
use super::Theme;
|
||||
|
||||
fn card(palette: &ContainerPalette) -> Style {
|
||||
Style {
|
||||
background: Some(Background::Color(palette.background)),
|
||||
text_color: palette.text,
|
||||
border: if let Some(color) = palette.border {
|
||||
Border {
|
||||
radius: 25.0.into(),
|
||||
width: 1.0,
|
||||
color,
|
||||
}
|
||||
} else {
|
||||
Border {
|
||||
..Default::default()
|
||||
}
|
||||
},
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn simple(theme: &Theme) -> Style {
|
||||
card(&theme.colors.cards.simple)
|
||||
}
|
||||
|
||||
pub fn modal(theme: &Theme) -> Style {
|
||||
card(&theme.colors.cards.modal)
|
||||
}
|
||||
|
||||
pub fn border(theme: &Theme) -> Style {
|
||||
card(&theme.colors.cards.border)
|
||||
}
|
||||
|
||||
pub fn invalid(theme: &Theme) -> Style {
|
||||
card(&theme.colors.cards.invalid)
|
||||
}
|
||||
|
||||
pub fn warning(theme: &Theme) -> Style {
|
||||
card(&theme.colors.cards.warning)
|
||||
}
|
||||
|
||||
pub fn error(theme: &Theme) -> Style {
|
||||
card(&theme.colors.cards.error)
|
||||
}
|
||||
37
liana-ui/src/theme/checkbox.rs
Normal file
37
liana-ui/src/theme/checkbox.rs
Normal file
@ -0,0 +1,37 @@
|
||||
use iced::{
|
||||
widget::checkbox::{Catalog, Status, Style, StyleFn},
|
||||
Border,
|
||||
};
|
||||
|
||||
use super::Theme;
|
||||
|
||||
impl Catalog for Theme {
|
||||
type Class<'a> = StyleFn<'a, Self>;
|
||||
|
||||
fn default<'a>() -> <Self as Catalog>::Class<'a> {
|
||||
Box::new(primary)
|
||||
}
|
||||
|
||||
fn style(&self, class: &<Self as Catalog>::Class<'_>, status: Status) -> Style {
|
||||
class(self, status)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn primary(theme: &Theme, _status: Status) -> Style {
|
||||
Style {
|
||||
icon_color: theme.colors.checkboxes.icon,
|
||||
text_color: theme.colors.checkboxes.text.into(),
|
||||
background: theme.colors.checkboxes.background.into(),
|
||||
border: if let Some(color) = theme.colors.checkboxes.border {
|
||||
Border {
|
||||
radius: 4.0.into(),
|
||||
width: 1.0,
|
||||
color,
|
||||
}
|
||||
} else {
|
||||
Border {
|
||||
..Default::default()
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
44
liana-ui/src/theme/container.rs
Normal file
44
liana-ui/src/theme/container.rs
Normal file
@ -0,0 +1,44 @@
|
||||
use iced::widget::container::{transparent, Catalog, Style, StyleFn};
|
||||
use iced::Background;
|
||||
|
||||
use super::Theme;
|
||||
|
||||
impl Catalog for Theme {
|
||||
type Class<'a> = StyleFn<'a, Self>;
|
||||
|
||||
fn default<'a>() -> Self::Class<'a> {
|
||||
Box::new(transparent)
|
||||
}
|
||||
|
||||
fn style(&self, class: &Self::Class<'_>) -> Style {
|
||||
class(self)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn background(theme: &Theme) -> Style {
|
||||
Style {
|
||||
background: Some(Background::Color(theme.colors.general.background)),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn foreground(theme: &Theme) -> Style {
|
||||
Style {
|
||||
background: Some(Background::Color(theme.colors.general.foreground)),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn border(theme: &Theme) -> Style {
|
||||
Style {
|
||||
background: Some(Background::Color(theme.colors.general.background)),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn custom(color: iced::Color) -> Box<dyn Fn(&Theme) -> Style> {
|
||||
Box::new(move |_theme: &Theme| Style {
|
||||
background: Some(Background::Color(color)),
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
33
liana-ui/src/theme/mod.rs
Normal file
33
liana-ui/src/theme/mod.rs
Normal file
@ -0,0 +1,33 @@
|
||||
pub mod badge;
|
||||
pub mod banner;
|
||||
pub mod button;
|
||||
pub mod card;
|
||||
pub mod checkbox;
|
||||
pub mod container;
|
||||
pub mod notification;
|
||||
pub mod overlay;
|
||||
pub mod palette;
|
||||
pub mod pick_list;
|
||||
pub mod pill;
|
||||
pub mod progress_bar;
|
||||
pub mod qr_code;
|
||||
pub mod radio;
|
||||
pub mod scrollable;
|
||||
pub mod slider;
|
||||
pub mod svg;
|
||||
pub mod text;
|
||||
pub mod text_input;
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Default)]
|
||||
pub struct Theme {
|
||||
pub colors: palette::Palette,
|
||||
}
|
||||
|
||||
impl iced::application::DefaultStyle for Theme {
|
||||
fn default_style(&self) -> iced::application::Appearance {
|
||||
iced::application::Appearance {
|
||||
background_color: self.colors.general.background,
|
||||
text_color: self.colors.text.primary,
|
||||
}
|
||||
}
|
||||
}
|
||||
32
liana-ui/src/theme/notification.rs
Normal file
32
liana-ui/src/theme/notification.rs
Normal file
@ -0,0 +1,32 @@
|
||||
use iced::widget::container::Style;
|
||||
use iced::{Background, Border};
|
||||
|
||||
use super::palette::ContainerPalette;
|
||||
use super::Theme;
|
||||
|
||||
fn notification(palette: &ContainerPalette) -> Style {
|
||||
Style {
|
||||
background: Some(Background::Color(palette.background)),
|
||||
text_color: palette.text,
|
||||
border: if let Some(color) = palette.border {
|
||||
Border {
|
||||
width: 1.0,
|
||||
color,
|
||||
radius: 25.0.into(),
|
||||
}
|
||||
} else {
|
||||
Border {
|
||||
..Default::default()
|
||||
}
|
||||
},
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn pending(theme: &Theme) -> Style {
|
||||
notification(&theme.colors.notifications.pending)
|
||||
}
|
||||
|
||||
pub fn error(theme: &Theme) -> Style {
|
||||
notification(&theme.colors.notifications.error)
|
||||
}
|
||||
38
liana-ui/src/theme/overlay.rs
Normal file
38
liana-ui/src/theme/overlay.rs
Normal file
@ -0,0 +1,38 @@
|
||||
use iced::{
|
||||
widget::overlay::menu::{Catalog, Style, StyleFn},
|
||||
Border,
|
||||
};
|
||||
|
||||
use super::Theme;
|
||||
|
||||
impl Catalog for Theme {
|
||||
type Class<'a> = StyleFn<'a, Self>;
|
||||
|
||||
fn default<'a>() -> <Self as Catalog>::Class<'a> {
|
||||
Box::new(primary)
|
||||
}
|
||||
|
||||
fn style(&self, class: &<Self as Catalog>::Class<'_>) -> Style {
|
||||
class(self)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn primary(theme: &Theme) -> Style {
|
||||
Style {
|
||||
text_color: theme.colors.text.primary,
|
||||
background: theme.colors.buttons.secondary.active.background.into(),
|
||||
selected_text_color: theme.colors.buttons.primary.active.text,
|
||||
selected_background: theme.colors.buttons.primary.active.background.into(),
|
||||
border: if let Some(color) = theme.colors.buttons.secondary.active.border {
|
||||
Border {
|
||||
radius: 25.0.into(),
|
||||
width: 1.0,
|
||||
color,
|
||||
}
|
||||
} else {
|
||||
Border {
|
||||
..Default::default()
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
508
liana-ui/src/theme/palette.rs
Normal file
508
liana-ui/src/theme/palette.rs
Normal file
@ -0,0 +1,508 @@
|
||||
use crate::color;
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub struct Palette {
|
||||
pub general: General,
|
||||
pub text: Text,
|
||||
pub buttons: Buttons,
|
||||
pub cards: Cards,
|
||||
pub banners: Banners,
|
||||
pub badges: Badges,
|
||||
pub pills: Pills,
|
||||
pub notifications: Notifications,
|
||||
pub text_inputs: TextInputs,
|
||||
pub checkboxes: Checkboxes,
|
||||
pub radio_buttons: RadioButtons,
|
||||
pub sliders: Sliders,
|
||||
pub progress_bars: ProgressBars,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub struct Text {
|
||||
pub primary: iced::Color,
|
||||
pub secondary: iced::Color,
|
||||
pub warning: iced::Color,
|
||||
pub success: iced::Color,
|
||||
pub error: iced::Color,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub struct General {
|
||||
pub background: iced::Color,
|
||||
pub foreground: iced::Color,
|
||||
pub scrollable: iced::Color,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub struct Buttons {
|
||||
pub transparent: Button,
|
||||
pub transparent_border: Button,
|
||||
pub primary: Button,
|
||||
pub secondary: Button,
|
||||
pub destructive: Button,
|
||||
pub container: Button,
|
||||
pub container_border: Button,
|
||||
pub menu: Button,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub struct Button {
|
||||
pub active: ButtonPalette,
|
||||
pub hovered: ButtonPalette,
|
||||
pub pressed: Option<ButtonPalette>,
|
||||
pub disabled: Option<ButtonPalette>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub struct ButtonPalette {
|
||||
pub background: iced::Color,
|
||||
pub text: iced::Color,
|
||||
pub border: Option<iced::Color>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub struct Containers {
|
||||
pub border: ContainerPalette,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub struct ContainerPalette {
|
||||
pub background: iced::Color,
|
||||
pub text: Option<iced::Color>,
|
||||
pub border: Option<iced::Color>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub struct Cards {
|
||||
pub simple: ContainerPalette,
|
||||
pub modal: ContainerPalette,
|
||||
pub border: ContainerPalette,
|
||||
pub invalid: ContainerPalette,
|
||||
pub warning: ContainerPalette,
|
||||
pub error: ContainerPalette,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub struct Banners {
|
||||
pub network: ContainerPalette,
|
||||
pub warning: ContainerPalette,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub struct Badges {
|
||||
pub simple: ContainerPalette,
|
||||
pub bitcoin: ContainerPalette,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub struct Pills {
|
||||
pub simple: ContainerPalette,
|
||||
pub primary: ContainerPalette,
|
||||
pub success: ContainerPalette,
|
||||
pub warning: ContainerPalette,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub struct Notifications {
|
||||
pub pending: ContainerPalette,
|
||||
pub error: ContainerPalette,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub struct TextInputs {
|
||||
pub primary: TextInput,
|
||||
pub invalid: TextInput,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub struct TextInput {
|
||||
pub active: TextInputPalette,
|
||||
pub disabled: TextInputPalette,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub struct TextInputPalette {
|
||||
pub background: iced::Color,
|
||||
pub icon: iced::Color,
|
||||
pub placeholder: iced::Color,
|
||||
pub value: iced::Color,
|
||||
pub selection: iced::Color,
|
||||
pub border: Option<iced::Color>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub struct Checkboxes {
|
||||
pub icon: iced::Color,
|
||||
pub text: iced::Color,
|
||||
pub background: iced::Color,
|
||||
pub border: Option<iced::Color>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub struct RadioButtons {
|
||||
pub dot: iced::Color,
|
||||
pub text: iced::Color,
|
||||
pub border: iced::Color,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub struct Sliders {
|
||||
pub background: iced::Color,
|
||||
pub border: iced::Color,
|
||||
pub rail_border: Option<iced::Color>,
|
||||
pub rail_backgrounds: (iced::Color, iced::Color),
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub struct ProgressBars {
|
||||
pub background: iced::Color,
|
||||
pub bar: iced::Color,
|
||||
pub border: Option<iced::Color>,
|
||||
}
|
||||
|
||||
impl std::default::Default for Palette {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
general: General {
|
||||
background: color::LIGHT_BLACK,
|
||||
foreground: color::BLACK,
|
||||
scrollable: color::GREY_7,
|
||||
},
|
||||
text: Text {
|
||||
primary: color::WHITE,
|
||||
secondary: color::GREY_3,
|
||||
warning: color::ORANGE,
|
||||
success: color::GREEN,
|
||||
error: color::RED,
|
||||
},
|
||||
buttons: Buttons {
|
||||
primary: Button {
|
||||
active: ButtonPalette {
|
||||
background: color::GREEN,
|
||||
text: color::LIGHT_BLACK,
|
||||
border: color::GREEN.into(),
|
||||
},
|
||||
hovered: ButtonPalette {
|
||||
background: color::GREEN,
|
||||
text: color::LIGHT_BLACK,
|
||||
border: color::GREEN.into(),
|
||||
},
|
||||
pressed: Some(ButtonPalette {
|
||||
background: color::GREEN,
|
||||
text: color::LIGHT_BLACK,
|
||||
border: color::GREEN.into(),
|
||||
}),
|
||||
disabled: Some(ButtonPalette {
|
||||
background: color::GREY_6,
|
||||
text: color::GREY_2,
|
||||
border: color::GREY_7.into(),
|
||||
}),
|
||||
},
|
||||
secondary: Button {
|
||||
active: ButtonPalette {
|
||||
background: color::GREY_6,
|
||||
text: color::GREY_2,
|
||||
border: color::GREY_7.into(),
|
||||
},
|
||||
hovered: ButtonPalette {
|
||||
background: color::GREY_6,
|
||||
text: color::GREEN,
|
||||
border: color::GREEN.into(),
|
||||
},
|
||||
pressed: Some(ButtonPalette {
|
||||
background: color::GREY_6,
|
||||
text: color::GREEN,
|
||||
border: color::GREEN.into(),
|
||||
}),
|
||||
disabled: Some(ButtonPalette {
|
||||
background: color::GREY_6,
|
||||
text: color::GREY_2,
|
||||
border: color::GREY_7.into(),
|
||||
}),
|
||||
},
|
||||
destructive: Button {
|
||||
active: ButtonPalette {
|
||||
background: color::GREY_6,
|
||||
text: color::RED,
|
||||
border: color::RED.into(),
|
||||
},
|
||||
hovered: ButtonPalette {
|
||||
background: color::RED,
|
||||
text: color::LIGHT_BLACK,
|
||||
border: color::RED.into(),
|
||||
},
|
||||
pressed: Some(ButtonPalette {
|
||||
background: color::RED,
|
||||
text: color::LIGHT_BLACK,
|
||||
border: color::RED.into(),
|
||||
}),
|
||||
disabled: Some(ButtonPalette {
|
||||
background: color::GREY_6,
|
||||
text: color::RED,
|
||||
border: color::RED.into(),
|
||||
}),
|
||||
},
|
||||
transparent: Button {
|
||||
active: ButtonPalette {
|
||||
background: color::TRANSPARENT,
|
||||
text: color::GREY_2,
|
||||
border: None,
|
||||
},
|
||||
hovered: ButtonPalette {
|
||||
background: color::TRANSPARENT,
|
||||
text: color::GREY_2,
|
||||
border: None,
|
||||
},
|
||||
pressed: Some(ButtonPalette {
|
||||
background: color::TRANSPARENT,
|
||||
text: color::GREY_2,
|
||||
border: None,
|
||||
}),
|
||||
disabled: Some(ButtonPalette {
|
||||
background: color::TRANSPARENT,
|
||||
text: color::GREY_2,
|
||||
border: None,
|
||||
}),
|
||||
},
|
||||
transparent_border: Button {
|
||||
active: ButtonPalette {
|
||||
background: color::TRANSPARENT,
|
||||
text: color::GREY_2,
|
||||
border: color::TRANSPARENT.into(),
|
||||
},
|
||||
hovered: ButtonPalette {
|
||||
background: color::TRANSPARENT,
|
||||
text: color::GREY_2,
|
||||
border: color::GREEN.into(),
|
||||
},
|
||||
pressed: Some(ButtonPalette {
|
||||
background: color::TRANSPARENT,
|
||||
text: color::GREY_2,
|
||||
border: color::GREEN.into(),
|
||||
}),
|
||||
disabled: Some(ButtonPalette {
|
||||
background: color::TRANSPARENT,
|
||||
text: color::GREY_2,
|
||||
border: color::TRANSPARENT.into(),
|
||||
}),
|
||||
},
|
||||
container: Button {
|
||||
active: ButtonPalette {
|
||||
background: color::TRANSPARENT,
|
||||
text: color::GREY_2,
|
||||
border: None,
|
||||
},
|
||||
hovered: ButtonPalette {
|
||||
background: color::TRANSPARENT,
|
||||
text: color::GREY_2,
|
||||
border: None,
|
||||
},
|
||||
pressed: Some(ButtonPalette {
|
||||
background: color::TRANSPARENT,
|
||||
text: color::GREY_2,
|
||||
border: None,
|
||||
}),
|
||||
disabled: Some(ButtonPalette {
|
||||
background: color::TRANSPARENT,
|
||||
text: color::GREY_2,
|
||||
border: None,
|
||||
}),
|
||||
},
|
||||
container_border: Button {
|
||||
active: ButtonPalette {
|
||||
background: color::TRANSPARENT,
|
||||
text: color::GREY_2,
|
||||
border: color::TRANSPARENT.into(),
|
||||
},
|
||||
hovered: ButtonPalette {
|
||||
background: color::TRANSPARENT,
|
||||
text: color::GREY_2,
|
||||
border: color::GREEN.into(),
|
||||
},
|
||||
pressed: Some(ButtonPalette {
|
||||
background: color::TRANSPARENT,
|
||||
text: color::GREY_2,
|
||||
border: color::GREEN.into(),
|
||||
}),
|
||||
disabled: Some(ButtonPalette {
|
||||
background: color::TRANSPARENT,
|
||||
text: color::GREY_2,
|
||||
border: color::TRANSPARENT.into(),
|
||||
}),
|
||||
},
|
||||
menu: Button {
|
||||
active: ButtonPalette {
|
||||
background: color::TRANSPARENT,
|
||||
text: color::WHITE,
|
||||
border: color::TRANSPARENT.into(),
|
||||
},
|
||||
hovered: ButtonPalette {
|
||||
background: color::LIGHT_BLACK,
|
||||
text: color::WHITE,
|
||||
border: color::TRANSPARENT.into(),
|
||||
},
|
||||
pressed: Some(ButtonPalette {
|
||||
background: color::LIGHT_BLACK,
|
||||
text: color::WHITE,
|
||||
border: color::TRANSPARENT.into(),
|
||||
}),
|
||||
disabled: Some(ButtonPalette {
|
||||
background: color::TRANSPARENT,
|
||||
text: color::WHITE,
|
||||
border: color::TRANSPARENT.into(),
|
||||
}),
|
||||
},
|
||||
},
|
||||
cards: Cards {
|
||||
simple: ContainerPalette {
|
||||
background: color::GREY_6,
|
||||
text: None,
|
||||
border: Some(color::TRANSPARENT),
|
||||
},
|
||||
modal: ContainerPalette {
|
||||
background: color::LIGHT_BLACK,
|
||||
text: None,
|
||||
border: color::TRANSPARENT.into(),
|
||||
},
|
||||
border: ContainerPalette {
|
||||
background: color::TRANSPARENT,
|
||||
text: None,
|
||||
border: color::GREY_7.into(),
|
||||
},
|
||||
invalid: ContainerPalette {
|
||||
background: color::LIGHT_BLACK,
|
||||
text: color::RED.into(),
|
||||
border: color::RED.into(),
|
||||
},
|
||||
warning: ContainerPalette {
|
||||
background: color::LIGHT_BLACK,
|
||||
text: color::ORANGE.into(),
|
||||
border: color::ORANGE.into(),
|
||||
},
|
||||
error: ContainerPalette {
|
||||
background: color::LIGHT_BLACK,
|
||||
text: color::RED.into(),
|
||||
border: color::RED.into(),
|
||||
},
|
||||
},
|
||||
banners: Banners {
|
||||
network: ContainerPalette {
|
||||
background: color::BLUE,
|
||||
text: color::LIGHT_BLACK.into(),
|
||||
border: None,
|
||||
},
|
||||
warning: ContainerPalette {
|
||||
background: color::ORANGE,
|
||||
text: color::LIGHT_BLACK.into(),
|
||||
border: None,
|
||||
},
|
||||
},
|
||||
badges: Badges {
|
||||
simple: ContainerPalette {
|
||||
background: color::GREY_4,
|
||||
text: None,
|
||||
border: color::TRANSPARENT.into(),
|
||||
},
|
||||
bitcoin: ContainerPalette {
|
||||
background: color::ORANGE,
|
||||
text: color::WHITE.into(),
|
||||
border: color::TRANSPARENT.into(),
|
||||
},
|
||||
},
|
||||
pills: Pills {
|
||||
primary: ContainerPalette {
|
||||
background: color::GREEN,
|
||||
text: color::LIGHT_BLACK.into(),
|
||||
border: color::TRANSPARENT.into(),
|
||||
},
|
||||
simple: ContainerPalette {
|
||||
background: color::TRANSPARENT,
|
||||
text: color::GREY_3.into(),
|
||||
border: color::GREY_3.into(),
|
||||
},
|
||||
warning: ContainerPalette {
|
||||
background: color::TRANSPARENT,
|
||||
text: color::RED.into(),
|
||||
border: color::RED.into(),
|
||||
},
|
||||
success: ContainerPalette {
|
||||
background: color::GREEN,
|
||||
text: color::LIGHT_BLACK.into(),
|
||||
border: color::GREEN.into(),
|
||||
},
|
||||
},
|
||||
notifications: Notifications {
|
||||
pending: ContainerPalette {
|
||||
background: color::GREEN,
|
||||
text: color::LIGHT_BLACK.into(),
|
||||
border: Some(color::GREEN),
|
||||
},
|
||||
error: ContainerPalette {
|
||||
background: color::ORANGE,
|
||||
text: color::LIGHT_BLACK.into(),
|
||||
border: Some(color::ORANGE),
|
||||
},
|
||||
},
|
||||
text_inputs: TextInputs {
|
||||
primary: TextInput {
|
||||
active: TextInputPalette {
|
||||
background: color::TRANSPARENT,
|
||||
icon: color::TRANSPARENT,
|
||||
placeholder: color::GREY_7,
|
||||
value: color::GREY_2,
|
||||
selection: color::GREEN,
|
||||
border: Some(color::GREY_7),
|
||||
},
|
||||
disabled: TextInputPalette {
|
||||
background: color::TRANSPARENT,
|
||||
icon: color::TRANSPARENT,
|
||||
placeholder: color::GREY_7,
|
||||
value: color::GREY_2,
|
||||
selection: color::GREEN,
|
||||
border: Some(color::GREY_7),
|
||||
},
|
||||
},
|
||||
invalid: TextInput {
|
||||
active: TextInputPalette {
|
||||
background: color::TRANSPARENT,
|
||||
icon: color::TRANSPARENT,
|
||||
placeholder: color::GREY_7,
|
||||
value: color::GREY_2,
|
||||
selection: color::GREEN,
|
||||
border: Some(color::RED),
|
||||
},
|
||||
disabled: TextInputPalette {
|
||||
background: color::TRANSPARENT,
|
||||
icon: color::TRANSPARENT,
|
||||
placeholder: color::GREY_7,
|
||||
value: color::TRANSPARENT,
|
||||
selection: color::GREEN,
|
||||
border: Some(color::RED),
|
||||
},
|
||||
},
|
||||
},
|
||||
checkboxes: Checkboxes {
|
||||
icon: color::GREEN,
|
||||
text: color::GREY_2,
|
||||
background: color::GREY_4,
|
||||
border: Some(color::GREY_4),
|
||||
},
|
||||
radio_buttons: RadioButtons {
|
||||
dot: color::GREEN,
|
||||
text: color::GREY_2,
|
||||
border: color::GREY_7,
|
||||
},
|
||||
sliders: Sliders {
|
||||
background: color::GREEN,
|
||||
border: color::GREEN,
|
||||
rail_border: None,
|
||||
rail_backgrounds: (color::GREEN, color::TRANSPARENT),
|
||||
},
|
||||
progress_bars: ProgressBars {
|
||||
bar: color::GREEN,
|
||||
border: color::TRANSPARENT.into(),
|
||||
background: color::GREY_6,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
38
liana-ui/src/theme/pick_list.rs
Normal file
38
liana-ui/src/theme/pick_list.rs
Normal file
@ -0,0 +1,38 @@
|
||||
use iced::{
|
||||
widget::pick_list::{Catalog, Status, Style, StyleFn},
|
||||
Border,
|
||||
};
|
||||
|
||||
use super::Theme;
|
||||
|
||||
impl Catalog for Theme {
|
||||
type Class<'a> = StyleFn<'a, Self>;
|
||||
|
||||
fn default<'a>() -> <Self as Catalog>::Class<'a> {
|
||||
Box::new(primary)
|
||||
}
|
||||
|
||||
fn style(&self, class: &<Self as Catalog>::Class<'_>, status: Status) -> Style {
|
||||
class(self, status)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn primary(theme: &Theme, _status: Status) -> Style {
|
||||
Style {
|
||||
text_color: theme.colors.buttons.secondary.active.text,
|
||||
placeholder_color: theme.colors.buttons.secondary.active.text,
|
||||
background: theme.colors.buttons.secondary.active.background.into(),
|
||||
border: if let Some(color) = theme.colors.buttons.secondary.active.border {
|
||||
Border {
|
||||
radius: 25.0.into(),
|
||||
width: 1.0,
|
||||
color,
|
||||
}
|
||||
} else {
|
||||
Border {
|
||||
..Default::default()
|
||||
}
|
||||
},
|
||||
handle_color: theme.colors.buttons.secondary.active.text,
|
||||
}
|
||||
}
|
||||
34
liana-ui/src/theme/pill.rs
Normal file
34
liana-ui/src/theme/pill.rs
Normal file
@ -0,0 +1,34 @@
|
||||
use iced::widget::container::Style;
|
||||
use iced::{Background, Border};
|
||||
|
||||
use super::palette::ContainerPalette;
|
||||
use super::Theme;
|
||||
|
||||
fn pill(palette: &ContainerPalette) -> Style {
|
||||
Style {
|
||||
background: Some(Background::Color(palette.background)),
|
||||
text_color: palette.text,
|
||||
border: Border {
|
||||
radius: 25.0.into(),
|
||||
width: 1.0,
|
||||
color: palette.border.unwrap_or_default(),
|
||||
},
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn simple(theme: &Theme) -> Style {
|
||||
pill(&theme.colors.pills.simple)
|
||||
}
|
||||
|
||||
pub fn primary(theme: &Theme) -> Style {
|
||||
pill(&theme.colors.pills.primary)
|
||||
}
|
||||
|
||||
pub fn success(theme: &Theme) -> Style {
|
||||
pill(&theme.colors.pills.success)
|
||||
}
|
||||
|
||||
pub fn warning(theme: &Theme) -> Style {
|
||||
pill(&theme.colors.pills.warning)
|
||||
}
|
||||
36
liana-ui/src/theme/progress_bar.rs
Normal file
36
liana-ui/src/theme/progress_bar.rs
Normal file
@ -0,0 +1,36 @@
|
||||
use iced::{
|
||||
widget::progress_bar::{Catalog, Style, StyleFn},
|
||||
Border,
|
||||
};
|
||||
|
||||
use super::Theme;
|
||||
|
||||
impl Catalog for Theme {
|
||||
type Class<'a> = StyleFn<'a, Self>;
|
||||
|
||||
fn default<'a>() -> <Self as Catalog>::Class<'a> {
|
||||
Box::new(primary)
|
||||
}
|
||||
|
||||
fn style(&self, class: &<Self as Catalog>::Class<'_>) -> Style {
|
||||
class(self)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn primary(theme: &Theme) -> Style {
|
||||
Style {
|
||||
background: theme.colors.progress_bars.background.into(),
|
||||
bar: theme.colors.progress_bars.bar.into(),
|
||||
border: if let Some(color) = theme.colors.cards.simple.border {
|
||||
Border {
|
||||
radius: 25.0.into(),
|
||||
width: 1.0,
|
||||
color,
|
||||
}
|
||||
} else {
|
||||
Border {
|
||||
..Default::default()
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
22
liana-ui/src/theme/qr_code.rs
Normal file
22
liana-ui/src/theme/qr_code.rs
Normal file
@ -0,0 +1,22 @@
|
||||
use iced::widget::qr_code::{Catalog, Style, StyleFn};
|
||||
|
||||
use super::Theme;
|
||||
|
||||
impl Catalog for Theme {
|
||||
type Class<'a> = StyleFn<'a, Self>;
|
||||
|
||||
fn default<'a>() -> Self::Class<'a> {
|
||||
Box::new(qr_code)
|
||||
}
|
||||
|
||||
fn style(&self, class: &Self::Class<'_>) -> Style {
|
||||
class(self)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn qr_code(_theme: &Theme) -> Style {
|
||||
Style {
|
||||
background: iced::Color::WHITE,
|
||||
cell: iced::Color::BLACK,
|
||||
}
|
||||
}
|
||||
25
liana-ui/src/theme/radio.rs
Normal file
25
liana-ui/src/theme/radio.rs
Normal file
@ -0,0 +1,25 @@
|
||||
use iced::widget::radio::{Catalog, Status, Style, StyleFn};
|
||||
|
||||
use super::Theme;
|
||||
|
||||
impl Catalog for Theme {
|
||||
type Class<'a> = StyleFn<'a, Self>;
|
||||
|
||||
fn default<'a>() -> <Self as Catalog>::Class<'a> {
|
||||
Box::new(primary)
|
||||
}
|
||||
|
||||
fn style(&self, class: &<Self as Catalog>::Class<'_>, status: Status) -> Style {
|
||||
class(self, status)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn primary(theme: &Theme, _status: Status) -> Style {
|
||||
Style {
|
||||
dot_color: theme.colors.radio_buttons.dot,
|
||||
text_color: theme.colors.radio_buttons.text.into(),
|
||||
background: theme.colors.cards.simple.background.into(),
|
||||
border_width: 1.0,
|
||||
border_color: theme.colors.radio_buttons.border,
|
||||
}
|
||||
}
|
||||
54
liana-ui/src/theme/scrollable.rs
Normal file
54
liana-ui/src/theme/scrollable.rs
Normal file
@ -0,0 +1,54 @@
|
||||
use iced::{
|
||||
widget::{
|
||||
container,
|
||||
scrollable::{Catalog, Rail, Scroller, Status, Style, StyleFn},
|
||||
},
|
||||
Border, Color, Shadow,
|
||||
};
|
||||
|
||||
use super::Theme;
|
||||
|
||||
impl Catalog for Theme {
|
||||
type Class<'a> = StyleFn<'a, Self>;
|
||||
|
||||
fn default<'a>() -> Self::Class<'a> {
|
||||
Box::new(primary)
|
||||
}
|
||||
|
||||
fn style(&self, class: &Self::Class<'_>, status: Status) -> Style {
|
||||
class(self, status)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn primary(theme: &Theme, status: Status) -> Style {
|
||||
let rail = Rail {
|
||||
background: None,
|
||||
border: Border::default(),
|
||||
scroller: Scroller {
|
||||
color: theme.colors.general.scrollable,
|
||||
border: Border {
|
||||
radius: 8.0.into(),
|
||||
width: 0.0,
|
||||
color: Color::TRANSPARENT,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
match status {
|
||||
Status::Active { .. } | Status::Hovered { .. } | Status::Dragged { .. } => Style {
|
||||
container: container::Style {
|
||||
text_color: None,
|
||||
background: None,
|
||||
border: Border {
|
||||
radius: 8.0.into(),
|
||||
width: 1.0,
|
||||
color: Color::TRANSPARENT,
|
||||
},
|
||||
shadow: Shadow::default(),
|
||||
},
|
||||
vertical_rail: rail,
|
||||
horizontal_rail: rail,
|
||||
gap: None,
|
||||
},
|
||||
}
|
||||
}
|
||||
50
liana-ui/src/theme/slider.rs
Normal file
50
liana-ui/src/theme/slider.rs
Normal file
@ -0,0 +1,50 @@
|
||||
use iced::{
|
||||
widget::slider::{Catalog, Handle, HandleShape, Rail, Status, Style, StyleFn},
|
||||
Border,
|
||||
};
|
||||
|
||||
use super::Theme;
|
||||
|
||||
impl Catalog for Theme {
|
||||
type Class<'a> = StyleFn<'a, Self>;
|
||||
|
||||
fn default<'a>() -> Self::Class<'a> {
|
||||
Box::new(slider)
|
||||
}
|
||||
|
||||
fn style(&self, class: &Self::Class<'_>, status: Status) -> Style {
|
||||
class(self, status)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn slider(theme: &Theme, _status: Status) -> Style {
|
||||
Style {
|
||||
rail: Rail {
|
||||
backgrounds: (
|
||||
theme.colors.sliders.rail_backgrounds.0.into(),
|
||||
theme.colors.sliders.rail_backgrounds.1.into(),
|
||||
),
|
||||
border: if let Some(color) = theme.colors.sliders.rail_border {
|
||||
Border {
|
||||
color,
|
||||
width: 1.0,
|
||||
radius: 4.0.into(),
|
||||
}
|
||||
} else {
|
||||
Border {
|
||||
..Default::default()
|
||||
}
|
||||
},
|
||||
width: 2.0,
|
||||
},
|
||||
handle: Handle {
|
||||
shape: HandleShape::Rectangle {
|
||||
width: 8,
|
||||
border_radius: 4.0.into(),
|
||||
},
|
||||
background: theme.colors.sliders.background.into(),
|
||||
border_color: theme.colors.sliders.border,
|
||||
border_width: 1.0,
|
||||
},
|
||||
}
|
||||
}
|
||||
19
liana-ui/src/theme/svg.rs
Normal file
19
liana-ui/src/theme/svg.rs
Normal file
@ -0,0 +1,19 @@
|
||||
use iced::widget::svg::{Catalog, Status, Style, StyleFn};
|
||||
|
||||
use super::Theme;
|
||||
|
||||
impl Catalog for Theme {
|
||||
type Class<'a> = StyleFn<'a, Self>;
|
||||
|
||||
fn default<'a>() -> Self::Class<'a> {
|
||||
Box::new(default)
|
||||
}
|
||||
|
||||
fn style(&self, class: &Self::Class<'_>, status: Status) -> Style {
|
||||
class(self, status)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn default(_theme: &Theme, _status: Status) -> Style {
|
||||
Style { color: None }
|
||||
}
|
||||
35
liana-ui/src/theme/text.rs
Normal file
35
liana-ui/src/theme/text.rs
Normal file
@ -0,0 +1,35 @@
|
||||
use iced::widget::text::{Catalog, Style, StyleFn};
|
||||
|
||||
use super::Theme;
|
||||
|
||||
impl Catalog for Theme {
|
||||
type Class<'a> = StyleFn<'a, Self>;
|
||||
|
||||
fn default<'a>() -> Self::Class<'a> {
|
||||
Box::new(default)
|
||||
}
|
||||
|
||||
fn style(&self, class: &Self::Class<'_>) -> Style {
|
||||
class(self)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn default(_theme: &Theme) -> Style {
|
||||
Style { color: None }
|
||||
}
|
||||
|
||||
pub fn primary(theme: &Theme) -> Style {
|
||||
Style {
|
||||
color: Some(theme.colors.text.primary),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn secondary(theme: &Theme) -> Style {
|
||||
Style {
|
||||
color: Some(theme.colors.text.secondary),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn custom(color: iced::Color) -> Style {
|
||||
Style { color: Some(color) }
|
||||
}
|
||||
65
liana-ui/src/theme/text_input.rs
Normal file
65
liana-ui/src/theme/text_input.rs
Normal file
@ -0,0 +1,65 @@
|
||||
use iced::{
|
||||
widget::text_input::{Catalog, Status, Style, StyleFn},
|
||||
Background, Border,
|
||||
};
|
||||
|
||||
use super::{palette::TextInput, Theme};
|
||||
|
||||
impl Catalog for Theme {
|
||||
type Class<'a> = StyleFn<'a, Self>;
|
||||
|
||||
fn default<'a>() -> Self::Class<'a> {
|
||||
Box::new(primary)
|
||||
}
|
||||
|
||||
fn style(&self, class: &Self::Class<'_>, status: Status) -> Style {
|
||||
class(self, status)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn primary(theme: &Theme, status: Status) -> Style {
|
||||
text_input(&theme.colors.text_inputs.primary, status)
|
||||
}
|
||||
|
||||
pub fn invalid(theme: &Theme, status: Status) -> Style {
|
||||
text_input(&theme.colors.text_inputs.invalid, status)
|
||||
}
|
||||
|
||||
fn text_input(c: &TextInput, status: Status) -> Style {
|
||||
let active = Style {
|
||||
background: Background::Color(c.active.background),
|
||||
border: if let Some(color) = c.active.border {
|
||||
Border {
|
||||
radius: 25.0.into(),
|
||||
width: 1.0,
|
||||
color,
|
||||
}
|
||||
} else {
|
||||
Border::default()
|
||||
},
|
||||
icon: c.active.icon,
|
||||
placeholder: c.active.placeholder,
|
||||
value: c.active.value,
|
||||
selection: c.active.selection,
|
||||
};
|
||||
|
||||
match status {
|
||||
Status::Active | Status::Hovered | Status::Focused { .. } => active,
|
||||
Status::Disabled => Style {
|
||||
background: Background::Color(c.disabled.background),
|
||||
border: if let Some(color) = c.disabled.border {
|
||||
Border {
|
||||
radius: 25.0.into(),
|
||||
width: 1.0,
|
||||
color,
|
||||
}
|
||||
} else {
|
||||
Border::default()
|
||||
},
|
||||
icon: c.disabled.icon,
|
||||
placeholder: c.disabled.placeholder,
|
||||
value: c.disabled.value,
|
||||
selection: c.disabled.selection,
|
||||
},
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user