diff --git a/gui/Cargo.lock b/gui/Cargo.lock index 1aaeb986..064ff420 100644 --- a/gui/Cargo.lock +++ b/gui/Cargo.lock @@ -1690,6 +1690,7 @@ dependencies = [ "iced_lazy", "iced_native", "liana", + "liana_ui", "log", "serde", "serde_json", @@ -1699,6 +1700,15 @@ dependencies = [ "tracing-subscriber", ] +[[package]] +name = "liana_ui" +version = "0.1.0" +dependencies = [ + "iced", + "iced_lazy", + "iced_native", +] + [[package]] name = "libc" version = "0.2.137" diff --git a/gui/Cargo.toml b/gui/Cargo.toml index 34d16347..084f5668 100644 --- a/gui/Cargo.toml +++ b/gui/Cargo.toml @@ -16,6 +16,7 @@ path = "src/main.rs" [dependencies] async-hwi = "0.0.4" liana = { git = "https://github.com/wizardsardine/liana", branch = "master", default-features = false } +liana_ui = { path = "ui" } backtrace = "0.3" base64 = "0.13" @@ -39,3 +40,6 @@ chrono = "0.4" [dev-dependencies] tokio = {version = "1.9.0", features = ["rt", "macros"]} + +[workspace] +members = ["ui"] diff --git a/gui/src/app/mod.rs b/gui/src/app/mod.rs index 1d31edca..5160edc1 100644 --- a/gui/src/app/mod.rs +++ b/gui/src/app/mod.rs @@ -15,10 +15,11 @@ use std::path::PathBuf; use std::sync::Arc; use std::time::Duration; -use iced::{clipboard, time, Command, Element, Subscription}; +use iced::{clipboard, time, Command, Subscription}; use tracing::{info, warn}; pub use liana::{config::Config as DaemonConfig, miniscript::bitcoin}; +use liana_ui::widget::Element; pub use config::Config; pub use message::Message; diff --git a/gui/src/app/state/coins.rs b/gui/src/app/state/coins.rs index dad584df..83119eca 100644 --- a/gui/src/app/state/coins.rs +++ b/gui/src/app/state/coins.rs @@ -1,7 +1,9 @@ use std::cmp::Ordering; use std::sync::Arc; -use iced::{Command, Element}; +use iced::Command; + +use liana_ui::widget::Element; use crate::{ app::{cache::Cache, error::Error, menu::Menu, message::Message, state::State, view}, diff --git a/gui/src/app/state/mod.rs b/gui/src/app/state/mod.rs index b95dea4d..9ffd6b17 100644 --- a/gui/src/app/state/mod.rs +++ b/gui/src/app/state/mod.rs @@ -8,8 +8,8 @@ use std::sync::Arc; use std::time::{SystemTime, UNIX_EPOCH}; use iced::{widget::qr_code, Command, Subscription}; -use iced::{widget::Column, Element}; use liana::miniscript::bitcoin::{Address, Amount}; +use liana_ui::widget::*; use super::{cache::Cache, error::Error, menu::Menu, message::Message, view, wallet::Wallet}; diff --git a/gui/src/app/state/recovery.rs b/gui/src/app/state/recovery.rs index cd0d7dcb..f6d9ac32 100644 --- a/gui/src/app/state/recovery.rs +++ b/gui/src/app/state/recovery.rs @@ -1,7 +1,9 @@ use std::str::FromStr; use std::sync::Arc; -use iced::{Command, Element}; +use iced::Command; + +use liana_ui::{component::form, widget::Element}; use crate::{ app::{ @@ -18,7 +20,6 @@ use crate::{ model::{remaining_sequence, Coin, SpendTx}, Daemon, }, - ui::component::form, }; use liana::miniscript::bitcoin::{Address, Amount}; diff --git a/gui/src/app/state/settings/bitcoind.rs b/gui/src/app/state/settings/bitcoind.rs index de5fe3e1..1d7d2431 100644 --- a/gui/src/app/state/settings/bitcoind.rs +++ b/gui/src/app/state/settings/bitcoind.rs @@ -5,15 +5,16 @@ use std::str::FromStr; use std::sync::Arc; use chrono::prelude::*; -use iced::{Command, Element}; +use iced::Command; use tracing::info; use liana::config::{BitcoinConfig, BitcoindConfig, Config}; +use liana_ui::{component::form, widget::Element}; + use crate::{ app::{cache::Cache, error::Error, message::Message, state::settings::Setting, view, State}, daemon::Daemon, - ui::component::form, }; #[derive(Debug)] diff --git a/gui/src/app/state/settings/mod.rs b/gui/src/app/state/settings/mod.rs index 1dfe931b..471a7e00 100644 --- a/gui/src/app/state/settings/mod.rs +++ b/gui/src/app/state/settings/mod.rs @@ -5,7 +5,9 @@ use std::convert::From; use std::path::PathBuf; use std::sync::Arc; -use iced::{Command, Element}; +use iced::Command; + +use liana_ui::widget::Element; use bitcoind::BitcoindSettingsState; use wallet::WalletSettingsState; diff --git a/gui/src/app/state/settings/wallet.rs b/gui/src/app/state/settings/wallet.rs index 10149449..90d78cf3 100644 --- a/gui/src/app/state/settings/wallet.rs +++ b/gui/src/app/state/settings/wallet.rs @@ -3,17 +3,21 @@ use std::convert::From; use std::path::PathBuf; use std::sync::Arc; -use iced::{Command, Element}; +use iced::Command; use liana::miniscript::bitcoin::{hashes::hex::ToHex, util::bip32::Fingerprint, Network}; +use liana_ui::{ + component::{form, modal}, + widget::Element, +}; + use crate::{ app::{ cache::Cache, error::Error, message::Message, settings, state::State, view, wallet::Wallet, }, daemon::Daemon, hw::{list_hardware_wallets, HardwareWallet, HardwareWalletConfig}, - ui::component::{form, modal}, }; pub struct WalletSettingsState { diff --git a/gui/src/app/state/spend/detail.rs b/gui/src/app/state/spend/detail.rs index 1c40fe98..4924bfa9 100644 --- a/gui/src/app/state/spend/detail.rs +++ b/gui/src/app/state/spend/detail.rs @@ -1,6 +1,6 @@ use std::sync::Arc; -use iced::{Command, Element}; +use iced::Command; use liana::{ descriptors::LianaDescInfo, miniscript::bitcoin::{ @@ -9,6 +9,11 @@ use liana::{ }, }; +use liana_ui::{ + component::{form, modal}, + widget::Element, +}; + use crate::{ app::{ cache::Cache, @@ -23,7 +28,6 @@ use crate::{ Daemon, }, hw::{list_hardware_wallets, HardwareWallet}, - ui::component::{form, modal}, }; trait Action { diff --git a/gui/src/app/state/spend/mod.rs b/gui/src/app/state/spend/mod.rs index 230167f5..771a9e88 100644 --- a/gui/src/app/state/spend/mod.rs +++ b/gui/src/app/state/spend/mod.rs @@ -2,9 +2,13 @@ pub mod detail; mod step; use std::sync::Arc; -use iced::{Command, Element}; +use iced::Command; use liana::miniscript::bitcoin::{consensus, util::psbt::Psbt}; +use liana_ui::{ + component::{form, modal}, + widget::Element, +}; use super::{redirect, State}; use crate::{ @@ -13,7 +17,6 @@ use crate::{ model::{Coin, SpendTx}, Daemon, }, - ui::component::{form, modal}, }; pub struct SpendPanel { diff --git a/gui/src/app/state/spend/step.rs b/gui/src/app/state/spend/step.rs index 9ac59f3c..5289c57c 100644 --- a/gui/src/app/state/spend/step.rs +++ b/gui/src/app/state/spend/step.rs @@ -2,7 +2,7 @@ use std::collections::HashMap; use std::str::FromStr; use std::sync::Arc; -use iced::{Command, Element}; +use iced::Command; use liana::{ descriptors::MultipathDescriptor, miniscript::bitcoin::{ @@ -10,6 +10,8 @@ use liana::{ }, }; +use liana_ui::{component::form, widget::Element}; + use crate::{ app::{ cache::Cache, error::Error, message::Message, state::spend::detail, view, wallet::Wallet, @@ -18,7 +20,6 @@ use crate::{ model::{remaining_sequence, Coin, SpendTx}, Daemon, }, - ui::component::form, }; /// See: https://github.com/wizardsardine/liana/blob/master/src/commands/mod.rs#L32 diff --git a/gui/src/app/view/coins.rs b/gui/src/app/view/coins.rs index fb1ede02..15e7a00f 100644 --- a/gui/src/app/view/coins.rs +++ b/gui/src/app/view/coins.rs @@ -1,6 +1,11 @@ -use iced::{ - widget::{Button, Column, Container, Row}, - Alignment, Element, Length, +use iced::{Alignment, Length}; + +use liana_ui::{ + color, + component::{badge, separation, text::*}, + icon, theme, + util::Collection, + widget::*, }; use crate::{ @@ -9,12 +14,6 @@ use crate::{ view::{message::Message, util::*}, }, daemon::model::{remaining_sequence, Coin}, - ui::{ - color, - component::{badge, button, card, separation, text::*}, - icon, - util::Collection, - }, }; pub fn coins_view<'a>( @@ -77,11 +76,11 @@ fn coin_list_view( Some(Container::new( Row::new() .spacing(5) - .push(text(" 0").small().style(color::ALERT)) + .push(text(" 0").small().style(color::legacy::ALERT)) .push( icon::hourglass_done_icon() .small() - .style(color::ALERT), + .style(color::legacy::ALERT), ) .align_items(Alignment::Center), )) @@ -92,12 +91,12 @@ fn coin_list_view( .push( text(format!(" {}", seq)) .small() - .style(color::WARNING), + .style(color::legacy::WARNING), ) .push( icon::hourglass_icon() .small() - .style(color::WARNING), + .style(color::legacy::WARNING), ) .align_items(Alignment::Center), )) @@ -124,7 +123,7 @@ fn coin_list_view( .align_items(Alignment::Center) .spacing(20), ) - .style(button::Style::TransparentBorder.into()) + .style(theme::Button::TransparentBorder) .padding(10) .on_press(Message::Select(index)), ) @@ -144,7 +143,7 @@ fn coin_list_view( text("The recovery path is available") .bold() .small() - .style(color::ALERT), + .style(color::legacy::ALERT), )) } else { Some(Container::new( @@ -169,7 +168,7 @@ fn coin_list_view( .push(text(format!("{}", coin.outpoint)).small()) .push(Button::new(icon::clipboard_icon()) .on_press(Message::Clipboard(coin.outpoint.to_string())) - .style(button::Style::TransparentBorder.into()) + .style(theme::Button::TransparentBorder) )) .spacing(5), ) @@ -204,5 +203,5 @@ fn coin_list_view( None }), ) - .style(card::SimpleCardStyle) + .style(theme::Container::Card(theme::Card::Simple)) } diff --git a/gui/src/app/view/home.rs b/gui/src/app/view/home.rs index e55b1ddd..7b4a30a2 100644 --- a/gui/src/app/view/home.rs +++ b/gui/src/app/view/home.rs @@ -1,18 +1,15 @@ use chrono::NaiveDateTime; -use iced::{ - alignment, - widget::{Button, Column, Container, Row}, - Alignment, Element, Length, -}; +use iced::{alignment, Alignment, Length}; -use crate::ui::{ - color, - component::{badge, button::Style, card, text::*}, - icon, - util::Collection, -}; use liana::miniscript::bitcoin; +use liana_ui::{ + color, + component::{badge, card, text::*}, + icon, theme, + util::Collection, + widget::*, +}; use crate::{ app::{ @@ -38,7 +35,11 @@ pub fn home_view<'a>( Row::new() .spacing(15) .align_items(Alignment::Center) - .push(icon::hourglass_icon().size(30).style(color::WARNING)) + .push( + icon::hourglass_icon() + .size(30) + .style(color::legacy::WARNING), + ) .push( Row::new() .spacing(5) @@ -56,7 +57,7 @@ pub fn home_view<'a>( Row::new() .spacing(15) .align_items(Alignment::Center) - .push(icon::hourglass_done_icon().style(color::ALERT)) + .push(icon::hourglass_done_icon().style(color::legacy::ALERT)) .push( Row::new() .spacing(5) @@ -97,11 +98,11 @@ pub fn home_view<'a>( ) .width(Length::Fill) .padding(15) - .style(Style::TransparentBorder.into()) + .style(theme::Button::TransparentBorder) .on_press(Message::Next), ) .width(Length::Fill) - .style(card::SimpleCardStyle), + .style(theme::Container::Card(theme::Card::Simple)), ) } else { None @@ -154,9 +155,9 @@ fn event_list_view<'a>(i: usize, event: &HistoryTransaction) -> Element<'a, Mess ) .padding(10) .on_press(Message::Select(i)) - .style(Style::TransparentBorder.into()), + .style(theme::Button::TransparentBorder), ) - .style(card::SimpleCardStyle) + .style(theme::Container::Card(theme::Card::Simple)) .into() } @@ -203,7 +204,7 @@ pub fn event_view<'a>(cache: &Cache, event: &'a HistoryTransaction) -> Element<' .push( Button::new(icon::clipboard_icon()) .on_press(Message::Clipboard(event.tx.txid().to_string())) - .style(Style::TransparentBorder.into()), + .style(theme::Button::TransparentBorder), ) .width(Length::Shrink), ), diff --git a/gui/src/app/view/hw.rs b/gui/src/app/view/hw.rs index 064c5e8c..8ee703b9 100644 --- a/gui/src/app/view/hw.rs +++ b/gui/src/app/view/hw.rs @@ -1,21 +1,14 @@ -use iced::{ - widget::{tooltip, Button, Column, Container, Row}, - Alignment, Element, Length, +use iced::{widget::tooltip, Alignment, Length}; + +use liana_ui::{ + color, + component::text::{text, Text}, + icon, theme, + util::Collection, + widget::*, }; -use crate::{ - app::view::message::*, - hw::HardwareWallet, - ui::{ - color, - component::{ - button, card, - text::{text, Text}, - }, - icon, - util::Collection, - }, -}; +use crate::{app::view::message::*, hw::HardwareWallet}; pub fn hw_list_view<'a>( i: usize, @@ -57,7 +50,7 @@ pub fn hw_list_view<'a>( message, tooltip::Position::Bottom, ) - .style(card::SimpleCardStyle), + .style(theme::Container::Card(theme::Card::Simple)), ), }) .spacing(5) @@ -76,20 +69,20 @@ pub fn hw_list_view<'a>( Row::new() .align_items(Alignment::Center) .spacing(5) - .push(icon::circle_check_icon().style(color::SUCCESS)) - .push(text(v).style(color::SUCCESS)) + .push(icon::circle_check_icon().style(color::legacy::SUCCESS)) + .push(text(v).style(color::legacy::SUCCESS)) })) .align_items(Alignment::Center) .width(Length::Fill), ) .padding(10) - .style(button::Style::Border.into()) + .style(theme::Button::Secondary) .width(Length::Fill); if !processing && hw.is_supported() { bttn = bttn.on_press(Message::SelectHardwareWallet(i)); } Container::new(bttn) .width(Length::Fill) - .style(card::SimpleCardStyle) + .style(theme::Container::Card(theme::Card::Simple)) .into() } diff --git a/gui/src/app/view/mod.rs b/gui/src/app/view/mod.rs index 7baf0cec..bd620e92 100644 --- a/gui/src/app/view/mod.rs +++ b/gui/src/app/view/mod.rs @@ -13,20 +13,19 @@ pub mod spend; pub use message::*; use warning::warn; -use iced::{ - widget::{self, scrollable, Button, Column, Container, Row}, - Element, Length, -}; +use iced::{widget::scrollable, Length}; -use crate::ui::{ - component::{badge, button, container, separation, text::*}, +use liana_ui::{ + component::{button, separation, text::*}, icon::{coin_icon, cross_icon, home_icon, receive_icon, send_icon, settings_icon}, + theme, util::Collection, + widget::*, }; use crate::app::{cache::Cache, error::Error, menu::Menu}; -pub fn sidebar<'a>(menu: &Menu, cache: &'a Cache) -> widget::Container<'a, Message> { +pub fn sidebar<'a>(menu: &Menu, cache: &'a Cache) -> Container<'a, Message> { let home_button = if *menu == Menu::Home { button::primary(Some(home_icon()), "Home") .on_press(Message::Reload) @@ -63,7 +62,7 @@ pub fn sidebar<'a>(menu: &Menu, cache: &'a Cache) -> widget::Container<'a, Messa .small() .bold(), ) - .style(badge::PillStyle::InversePrimary), + .style(theme::Container::Pill(theme::Pill::InversePrimary)), ) .spacing(10) .width(iced::Length::Fill) @@ -73,7 +72,7 @@ pub fn sidebar<'a>(menu: &Menu, cache: &'a Cache) -> widget::Container<'a, Messa .padding(5) .center_x(), ) - .style(button::Style::Primary.into()) + .style(theme::Button::Primary) .on_press(Message::Reload) .width(iced::Length::Units(200)) } else { @@ -102,7 +101,7 @@ pub fn sidebar<'a>(menu: &Menu, cache: &'a Cache) -> widget::Container<'a, Messa .small() .bold(), ) - .style(badge::PillStyle::Primary), + .style(theme::Pill::Primary), ) .spacing(10) .width(iced::Length::Fill) @@ -112,7 +111,7 @@ pub fn sidebar<'a>(menu: &Menu, cache: &'a Cache) -> widget::Container<'a, Messa .padding(5) .center_x(), ) - .style(button::Style::Transparent.into()) + .style(theme::Button::Transparent) .on_press(Message::Menu(Menu::Coins)) .width(iced::Length::Units(200)) }; @@ -138,7 +137,7 @@ pub fn sidebar<'a>(menu: &Menu, cache: &'a Cache) -> widget::Container<'a, Messa .small() .bold(), ) - .style(badge::PillStyle::InversePrimary), + .style(theme::Pill::InversePrimary), ) }) .spacing(10) @@ -149,7 +148,7 @@ pub fn sidebar<'a>(menu: &Menu, cache: &'a Cache) -> widget::Container<'a, Messa .padding(5) .center_x(), ) - .style(button::Style::Primary.into()) + .style(theme::Button::Primary) .on_press(Message::Reload) .width(iced::Length::Units(200)) } else { @@ -173,7 +172,7 @@ pub fn sidebar<'a>(menu: &Menu, cache: &'a Cache) -> widget::Container<'a, Messa .small() .bold(), ) - .style(badge::PillStyle::Primary), + .style(theme::Pill::Primary), ) }) .spacing(10) @@ -184,7 +183,7 @@ pub fn sidebar<'a>(menu: &Menu, cache: &'a Cache) -> widget::Container<'a, Messa .padding(5) .center_x(), ) - .style(button::Style::Transparent.into()) + .style(theme::Button::Transparent) .on_press(Message::Menu(Menu::Spend)) .width(iced::Length::Units(200)) }; @@ -234,14 +233,14 @@ pub fn sidebar<'a>(menu: &Menu, cache: &'a Cache) -> widget::Container<'a, Messa .push_maybe(cache.rescan_progress.map(|p| { Container::new(text(format!(" Rescan...{:.2}% ", p * 100.0))) .padding(5) - .style(badge::PillStyle::Simple) + .style(theme::Pill::Simple) })) .push(settings_button), ) .height(Length::Shrink), ), ) - .style(container::Style::Sidebar) + .style(theme::Container::Foreground) } pub fn dashboard<'a, T: Into>>( @@ -268,9 +267,9 @@ pub fn dashboard<'a, T: Into>>( .into() } -fn main_section<'a, T: 'a>(menu: widget::Container<'a, T>) -> widget::Container<'a, T> { +fn main_section<'a, T: 'a>(menu: Container<'a, T>) -> Container<'a, T> { Container::new(menu.max_width(1500)) - .style(container::Style::Background) + .style(theme::Container::Background) .center_x() .width(Length::Fill) .height(Length::Fill) @@ -300,7 +299,7 @@ pub fn modal<'a, T: Into>, F: Into>>( .push(button::primary(Some(cross_icon()), "Close").on_press(Message::Close)), ) .padding(10) - .style(container::Style::Background), + .style(theme::Container::Background), ) .push(modal_section(Container::new(scrollable(content)))) .push_maybe(fixed_footer) @@ -309,9 +308,9 @@ pub fn modal<'a, T: Into>, F: Into>>( .into() } -fn modal_section<'a, T: 'a>(menu: widget::Container<'a, T>) -> widget::Container<'a, T> { +fn modal_section<'a, T: 'a>(menu: Container<'a, T>) -> Container<'a, T> { Container::new(menu.max_width(1500)) - .style(container::Style::Background) + .style(theme::Container::Background) .center_x() .width(Length::Fill) .height(Length::Fill) diff --git a/gui/src/app/view/receive.rs b/gui/src/app/view/receive.rs index 7e6a9706..fd78747c 100644 --- a/gui/src/app/view/receive.rs +++ b/gui/src/app/view/receive.rs @@ -1,16 +1,14 @@ use iced::{ - widget::{ - qr_code::{self, QRCode}, - Button, Column, Row, - }, - Alignment, Element, + widget::qr_code::{self, QRCode}, + Alignment, }; use liana::miniscript::bitcoin; -use crate::ui::{ - component::{button, card, text::*}, - icon, +use liana_ui::{ + component::{card, text::*}, + icon, theme, + widget::*, }; use super::message::Message; @@ -25,7 +23,7 @@ pub fn receive<'a>(address: &'a bitcoin::Address, qr: &'a qr_code::State) -> Ele .push( Button::new(icon::clipboard_icon()) .on_press(Message::Clipboard(address.to_string())) - .style(button::Style::TransparentBorder.into()), + .style(theme::Button::TransparentBorder), ) .align_items(Alignment::Center), ) diff --git a/gui/src/app/view/recovery.rs b/gui/src/app/view/recovery.rs index c4367e7f..b03e40e5 100644 --- a/gui/src/app/view/recovery.rs +++ b/gui/src/app/view/recovery.rs @@ -1,19 +1,16 @@ -use iced::{ - widget::{Column, Container, Row, Space}, - Alignment, Element, Length, -}; +use iced::{widget::Space, Alignment, Length}; use liana::miniscript::bitcoin::Amount; -use crate::{ - app::view::message::{CreateSpendMessage, Message}, - ui::{ - component::{button, form, text::*}, - icon, - util::Collection, - }, +use liana_ui::{ + component::{button, form, text::*}, + icon, + util::Collection, + widget::*, }; +use crate::app::view::message::{CreateSpendMessage, Message}; + #[allow(clippy::too_many_arguments)] pub fn recovery<'a>( locked_coins: &(usize, Amount), diff --git a/gui/src/app/view/settings.rs b/gui/src/app/view/settings.rs index 5cd64f3d..c1e014fd 100644 --- a/gui/src/app/view/settings.rs +++ b/gui/src/app/view/settings.rs @@ -1,16 +1,20 @@ use std::collections::HashSet; use std::str::FromStr; -use iced::{ - alignment, - widget::{self, Button, Column, Container, ProgressBar, Row, Space}, - Alignment, Element, Length, -}; +use iced::{alignment, widget::Space, Alignment, Length}; use liana::miniscript::bitcoin::{util::bip32::Fingerprint, Network}; use super::{dashboard, message::*}; +use liana_ui::{ + color, + component::{badge, button, card, form, separation, text::*, tooltip::tooltip}, + icon, theme, + util::Collection, + widget::*, +}; + use crate::{ app::{ cache::Cache, @@ -19,12 +23,6 @@ use crate::{ view::{hw, warning::warn}, }, hw::HardwareWallet, - ui::{ - color, - component::{badge, button, card, form, separation, text::*, tooltip::tooltip}, - icon, - util::Collection, - }, }; pub fn list(cache: &Cache) -> Element { @@ -37,7 +35,7 @@ pub fn list(cache: &Cache) -> Element { .width(Length::Fill) .push( Button::new(text("Settings").size(30).bold()) - .style(button::Style::Transparent.into()) + .style(theme::Button::Transparent) .on_press(Message::Menu(Menu::Settings))) .push( Container::new( @@ -51,11 +49,11 @@ pub fn list(cache: &Cache) -> Element { .width(Length::Fill), ) .width(Length::Fill) - .style(button::Style::Border.into()) + .style(theme::Button::Secondary) .on_press(Message::Settings(SettingsMessage::EditBitcoindSettings)) ) .width(Length::Fill) - .style(card::SimpleCardStyle) + .style(theme::Container::Card(theme::Card::Simple)) ) .push( Container::new( @@ -69,11 +67,11 @@ pub fn list(cache: &Cache) -> Element { .width(Length::Fill), ) .width(Length::Fill) - .style(button::Style::Border.into()) + .style(theme::Button::Secondary) .on_press(Message::Settings(SettingsMessage::EditWalletSettings)) ) .width(Length::Fill) - .style(card::SimpleCardStyle) + .style(theme::Container::Card(theme::Card::Simple)) ) .push( Container::new( @@ -88,11 +86,11 @@ pub fn list(cache: &Cache) -> Element { .width(Length::Fill), ) .width(Length::Fill) - .style(button::Style::Border.into()) + .style(theme::Button::Secondary) .on_press(Message::Menu(Menu::Recovery)) ) .width(Length::Fill) - .style(card::SimpleCardStyle) + .style(theme::Container::Card(theme::Card::Simple)) ) .push( Container::new( @@ -106,11 +104,11 @@ pub fn list(cache: &Cache) -> Element { .width(Length::Fill), ) .width(Length::Fill) - .style(button::Style::Border.into()) + .style(theme::Button::Secondary) .on_press(Message::Settings(SettingsMessage::AboutSection)) ) .width(Length::Fill) - .style(card::SimpleCardStyle) + .style(theme::Container::Card(theme::Card::Simple)) ) ) } @@ -131,17 +129,17 @@ pub fn bitcoind_settings<'a>( .align_items(Alignment::Center) .push( Button::new(text("Settings").size(30).bold()) - .style(button::Style::Transparent.into()) + .style(theme::Button::Transparent) .on_press(Message::Menu(Menu::Settings)), ) .push(icon::chevron_right().size(30)) .push( Button::new(text("Bitcoin Core").size(30).bold()) - .style(button::Style::Transparent.into()) + .style(theme::Button::Transparent) .on_press(Message::Settings(SettingsMessage::EditBitcoindSettings)), ), ) - .push(widget::Column::with_children(settings).spacing(20)), + .push(Column::with_children(settings).spacing(20)), ) } @@ -162,13 +160,13 @@ pub fn about_section<'a>( .align_items(Alignment::Center) .push( Button::new(text("Settings").size(30).bold()) - .style(button::Style::Transparent.into()) + .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(button::Style::Transparent.into()) + .style(theme::Button::Transparent) .on_press(Message::Settings(SettingsMessage::AboutSection)), ), ) @@ -374,12 +372,11 @@ pub fn bitcoind<'a>( .width(Length::Fill), ) .push(if can_edit { - widget::Button::new(icon::pencil_icon()) - .style(button::Style::TransparentBorder.into()) + Button::new(icon::pencil_icon()) + .style(theme::Button::TransparentBorder) .on_press(SettingsEditMessage::Select) } else { - widget::Button::new(icon::pencil_icon()) - .style(button::Style::TransparentBorder.into()) + Button::new(icon::pencil_icon()).style(theme::Button::TransparentBorder) }) .align_items(Alignment::Center), ) @@ -391,20 +388,20 @@ pub fn bitcoind<'a>( .into() } -pub fn is_running_label<'a, T: 'a>(is_running: Option) -> widget::Container<'a, T> { +pub fn is_running_label<'a, T: 'a>(is_running: Option) -> Container<'a, T> { if let Some(running) = is_running { if running { Container::new( Row::new() - .push(icon::dot_icon().size(5).style(color::SUCCESS)) - .push(text("Running").small().style(color::SUCCESS)) + .push(icon::dot_icon().size(5).style(color::legacy::SUCCESS)) + .push(text("Running").small().style(color::legacy::SUCCESS)) .align_items(Alignment::Center), ) } else { Container::new( Row::new() - .push(icon::dot_icon().size(5).style(color::ALERT)) - .push(text("Not running").small().style(color::ALERT)) + .push(icon::dot_icon().size(5).style(color::legacy::ALERT)) + .push(text("Not running").small().style(color::legacy::ALERT)) .align_items(Alignment::Center), ) } @@ -429,7 +426,7 @@ pub fn rescan<'a>( .push(badge::Badge::new(icon::block_icon())) .push(text("Rescan blockchain").bold().width(Length::Fill)) .push_maybe(if success { - Some(text("Rescan was successful").style(color::SUCCESS)) + Some(text("Rescan was successful").style(color::legacy::SUCCESS)) } else { None }) @@ -539,13 +536,13 @@ pub fn wallet_settings<'a>( .align_items(Alignment::Center) .push( Button::new(text("Settings").size(30).bold()) - .style(button::Style::Transparent.into()) + .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(button::Style::Transparent.into()) + .style(theme::Button::Transparent) .on_press(Message::Settings(SettingsMessage::AboutSection)), ), ) @@ -604,8 +601,10 @@ pub fn wallet_settings<'a>( Some( Row::new() .align_items(Alignment::Center) - .push(icon::circle_check_icon().style(color::SUCCESS)) - .push(text("Updated").style(color::SUCCESS)), + .push( + icon::circle_check_icon().style(color::legacy::SUCCESS), + ) + .push(text("Updated").style(color::legacy::SUCCESS)), ) } else { None diff --git a/gui/src/app/view/spend/detail.rs b/gui/src/app/view/spend/detail.rs index df9992e5..95e28429 100644 --- a/gui/src/app/view/spend/detail.rs +++ b/gui/src/app/view/spend/detail.rs @@ -1,8 +1,8 @@ use std::collections::HashMap; use iced::{ - widget::{scrollable, tooltip, Button, Column, Container, Row, Scrollable, Space}, - Alignment, Element, Length, + widget::{scrollable, tooltip, Space}, + Alignment, Length, }; use liana::{ @@ -13,6 +13,19 @@ use liana::{ }, }; +use liana_ui::{ + color, + component::{ + badge, button, card, + collapse::Collapse, + form, separation, + text::{text, Text}, + }, + icon, theme, + util::Collection, + widget::*, +}; + use crate::{ app::{ error::Error, @@ -20,17 +33,6 @@ use crate::{ }, daemon::model::{Coin, SpendStatus, SpendTx}, hw::HardwareWallet, - ui::{ - color, - component::{ - badge, button, card, - collapse::Collapse, - container, form, separation, - text::{text, Text}, - }, - icon, - util::Collection, - }, }; pub fn spend_view<'a>( @@ -178,16 +180,16 @@ pub fn spend_modal<'a, T: Into>>( }), ) .padding(10) - .style(container::Style::Background), + .style(theme::Container::Background), ) .push( - Container::new(Scrollable::new( + Container::new(scrollable( Container::new(Container::new(content).max_width(800)) .width(Length::Fill) .center_x(), )) .height(Length::Fill) - .style(container::Style::Background), + .style(theme::Container::Background), ) .width(Length::Fill) .height(Length::Fill) @@ -200,7 +202,7 @@ fn spend_header<'a>(tx: &SpendTx) -> Element<'a, Message> { .align_items(Alignment::Center) .push( Row::new() - .push(badge::Badge::new(icon::send_icon()).style(badge::Style::Standard)) + .push(badge::Badge::new(icon::send_icon()).style(theme::Badge::Standard)) .push(if tx.sigs.recovery_path().is_some() { text("Recovery").bold() } else { @@ -266,14 +268,14 @@ fn spend_overview_view<'a>( .on_press(Message::Clipboard( tx.psbt.unsigned_tx.txid().to_string(), )) - .style(button::Style::TransparentBorder.into()), + .style(theme::Button::TransparentBorder), ) .align_items(Alignment::Center), ), ) .push(signatures(tx, desc_info, key_aliases)), ) - .style(card::SimpleCardStyle) + .style(theme::Container::Card(theme::Card::Simple)) .into() } @@ -286,12 +288,12 @@ pub fn signatures<'a>( .push( if let Some(sigs) = tx.path_ready() { Container::new( - Scrollable::new( + scrollable( Row::new() .spacing(5) .align_items(Alignment::Center) - .push(icon::circle_check_icon().style(color::SUCCESS)) - .push(text("Ready").bold().style(color::SUCCESS)) + .push(icon::circle_check_icon().style(color::legacy::SUCCESS)) + .push(text("Ready").bold().style(color::legacy::SUCCESS)) .push(text(", signed by")) .push( sigs.signed_pubkeys @@ -302,16 +304,16 @@ pub fn signatures<'a>( tooltip::Tooltip::new( Container::new(text(alias)) .padding(3) - .style(badge::PillStyle::Simple), + .style(theme::Container::Pill(theme::Pill::Simple)), value.0.to_string(), tooltip::Position::Bottom, ) - .style(card::SimpleCardStyle), + .style(theme::Container::Card(theme::Card::Simple)), ) } else { Container::new(text(value.0.to_string())) .padding(3) - .style(badge::PillStyle::Simple) + .style(theme::Container::Pill(theme::Pill::Simple)) }) }), ) @@ -335,7 +337,7 @@ pub fn signatures<'a>( ) .padding(15) .width(Length::Fill) - .style(button::Style::TransparentBorder.into()) + .style(theme::Button::TransparentBorder) }, move || { Button::new( @@ -353,7 +355,7 @@ pub fn signatures<'a>( ) .padding(15) .width(Length::Fill) - .style(button::Style::TransparentBorder.into()) + .style(theme::Button::TransparentBorder) }, move || { Into::>::into( @@ -423,11 +425,11 @@ pub fn path_view<'a>( sigs.threshold - sigs.sigs_count }; keys.sort(); - Scrollable::new( + scrollable( Row::new() .align_items(Alignment::Center) .push(if sigs.sigs_count >= sigs.threshold { - icon::circle_check_icon().style(color::SUCCESS) + icon::circle_check_icon().style(color::legacy::SUCCESS) } else { icon::circle_cross_icon() }) @@ -452,16 +454,16 @@ pub fn path_view<'a>( tooltip::Tooltip::new( Container::new(text(alias)) .padding(3) - .style(badge::PillStyle::Simple), + .style(theme::Container::Pill(theme::Pill::Simple)), value.0.to_string(), tooltip::Position::Bottom, ) - .style(card::SimpleCardStyle), + .style(theme::Container::Card(theme::Card::Simple)), ) } else { Container::new(text(value.0.to_string())) .padding(3) - .style(badge::PillStyle::Simple) + .style(theme::Container::Pill(theme::Pill::Simple)) }) } else { None @@ -482,16 +484,16 @@ pub fn path_view<'a>( tooltip::Tooltip::new( Container::new(text(alias)) .padding(3) - .style(badge::PillStyle::Simple), + .style(theme::Container::Pill(theme::Pill::Simple)), value.0.to_string(), tooltip::Position::Bottom, ) - .style(card::SimpleCardStyle), + .style(theme::Container::Card(theme::Card::Simple)), ) } else { Container::new(text(value.0.to_string())) .padding(3) - .style(badge::PillStyle::Simple) + .style(theme::Container::Pill(theme::Pill::Simple)) }) }), ), @@ -531,7 +533,7 @@ pub fn inputs_and_outputs_view<'a>( ) .padding(15) .width(Length::Fill) - .style(button::Style::TransparentBorder.into()) + .style(theme::Button::TransparentBorder) }, move || { Button::new( @@ -550,7 +552,7 @@ pub fn inputs_and_outputs_view<'a>( ) .padding(15) .width(Length::Fill) - .style(button::Style::TransparentBorder.into()) + .style(theme::Button::TransparentBorder) }, move || { coins @@ -575,7 +577,7 @@ pub fn inputs_and_outputs_view<'a>( coin.outpoint.to_string(), )) .style( - button::Style::TransparentBorder.into(), + theme::Button::TransparentBorder, ), ), ) @@ -585,7 +587,7 @@ pub fn inputs_and_outputs_view<'a>( .into() }, )) - .style(card::SimpleCardStyle), + .style(theme::Container::Card(theme::Card::Simple)), ) } else { None @@ -609,7 +611,7 @@ pub fn inputs_and_outputs_view<'a>( ) .padding(15) .width(Length::Fill) - .style(button::Style::TransparentBorder.into()) + .style(theme::Button::TransparentBorder) }, move || { Button::new( @@ -628,7 +630,7 @@ pub fn inputs_and_outputs_view<'a>( ) .padding(15) .width(Length::Fill) - .style(button::Style::TransparentBorder.into()) + .style(theme::Button::TransparentBorder) }, move || { tx.output @@ -655,7 +657,7 @@ pub fn inputs_and_outputs_view<'a>( addr.to_string(), )) .style( - button::Style::TransparentBorder.into(), + theme::Button::TransparentBorder, ), ), ) @@ -669,7 +671,7 @@ pub fn inputs_and_outputs_view<'a>( Some( Container::new(text("Change")) .padding(5) - .style(badge::PillStyle::Success), + .style(theme::Container::Pill(theme::Pill::Success)), ) } else { None @@ -684,7 +686,7 @@ pub fn inputs_and_outputs_view<'a>( Some( Container::new(text("Deposit")) .padding(5) - .style(badge::PillStyle::Success), + .style(theme::Container::Pill(theme::Pill::Success)), ) } else { None @@ -698,7 +700,7 @@ pub fn inputs_and_outputs_view<'a>( .into() }, )) - .style(card::SimpleCardStyle), + .style(theme::Container::Card(theme::Card::Simple)), ), ) .into() @@ -768,9 +770,10 @@ pub fn sign_action<'a>( .align_items(Alignment::Center) .spacing(5) .push( - icon::circle_check_icon().style(color::SUCCESS), + icon::circle_check_icon() + .style(color::legacy::SUCCESS), ) - .push(text("Signed").style(color::SUCCESS)), + .push(text("Signed").style(color::legacy::SUCCESS)), ) } else { None @@ -778,7 +781,7 @@ pub fn sign_action<'a>( ) .on_press(Message::Spend(SpendTxMessage::SelectHotSigner)) .padding(10) - .style(button::Style::Border.into()) + .style(theme::Button::Secondary) .width(Length::Fill) })) .width(Length::Fill), @@ -844,7 +847,7 @@ pub fn update_spend_success_view<'a>() -> Element<'a, Message> { Column::new() .push( card::simple(Container::new( - text("Spend transaction is updated").style(color::SUCCESS), + text("Spend transaction is updated").style(color::legacy::SUCCESS), )) .padding(50), ) diff --git a/gui/src/app/view/spend/mod.rs b/gui/src/app/view/spend/mod.rs index 27e121de..465d2e60 100644 --- a/gui/src/app/view/spend/mod.rs +++ b/gui/src/app/view/spend/mod.rs @@ -1,20 +1,19 @@ pub mod detail; pub mod step; -use iced::{ - widget::{Button, Column, Container, Row, Space}, - Alignment, Element, Length, +use iced::{widget::Space, Alignment, Length}; + +use liana_ui::{ + color, + component::{badge, button, card, form, text::*}, + icon, theme, + util::Collection, + widget::*, }; use crate::{ app::{error::Error, menu::Menu, view::util::*}, daemon::model::{SpendStatus, SpendTx}, - ui::{ - color, - component::{badge, button, card, form, text::*}, - icon, - util::Collection, - }, }; use super::{message::*, warning::warn}; @@ -57,7 +56,7 @@ pub fn import_spend_success_view<'a>() -> Element<'a, Message> { Column::new() .push( card::simple(Container::new( - text("PSBT is imported").style(color::SUCCESS), + text("PSBT is imported").style(color::legacy::SUCCESS), )) .padding(50), ) @@ -133,7 +132,7 @@ fn spend_tx_list_view<'a>(i: usize, tx: &SpendTx) -> Element<'a, Message> { .push( Container::new(text(" Recovery ").small()) .padding(3) - .style(badge::PillStyle::Simple), + .style(theme::Container::Pill(theme::Pill::Simple)), ) } else { let sigs = tx.sigs.primary_path(); @@ -172,8 +171,8 @@ fn spend_tx_list_view<'a>(i: usize, tx: &SpendTx) -> Element<'a, Message> { ) .padding(10) .on_press(Message::Select(i)) - .style(button::Style::TransparentBorder.into()), + .style(theme::Button::TransparentBorder), ) - .style(card::SimpleCardStyle) + .style(theme::Container::Card(theme::Card::Simple)) .into() } diff --git a/gui/src/app/view/spend/step.rs b/gui/src/app/view/spend/step.rs index 5f69ad97..c151223a 100644 --- a/gui/src/app/view/spend/step.rs +++ b/gui/src/app/view/spend/step.rs @@ -1,10 +1,18 @@ -use iced::{ - widget::{self, Button, Column, Container, Row}, - Alignment, Element, Length, -}; +use iced::{Alignment, Length}; use liana::miniscript::bitcoin::Amount; +use liana_ui::{ + color, + component::{ + badge, button, form, + text::{text, Text}, + }, + icon, theme, + util::Collection, + widget::*, +}; + use crate::{ app::{ cache::Cache, @@ -12,15 +20,6 @@ use crate::{ view::{message::*, modal, util::amount}, }, daemon::model::{remaining_sequence, Coin}, - ui::{ - color, - component::{ - badge, button, card, form, - text::{text, Text}, - }, - icon, - util::Collection, - }, }; pub fn choose_recipients_view<'a>( @@ -37,7 +36,7 @@ pub fn choose_recipients_view<'a>( .push(text("Choose recipients").bold().size(50)) .push( Column::new() - .push(widget::Column::with_children(recipients).spacing(10)) + .push(Column::with_children(recipients).spacing(10)) .push( button::transparent(Some(icon::plus_icon()), "Add recipient") .on_press(Message::CreateSpend(CreateSpendMessage::AddRecipient)), @@ -64,7 +63,10 @@ pub fn choose_recipients_view<'a>( .width(Length::Fill), ) .push_maybe(if duplicate { - Some(text("Two recipient addresses are the same").style(color::WARNING)) + Some( + text("Two recipient addresses are the same") + .style(color::legacy::WARNING), + ) } else { None }) @@ -213,9 +215,11 @@ fn coin_list_view<'a>( Some(Container::new( Row::new() .spacing(5) - .push(text(" 0").small().style(color::ALERT)) + .push(text(" 0").small().style(color::legacy::ALERT)) .push( - icon::hourglass_done_icon().small().style(color::ALERT), + icon::hourglass_done_icon() + .small() + .style(color::legacy::ALERT), ) .align_items(Alignment::Center), )) @@ -224,9 +228,15 @@ fn coin_list_view<'a>( Row::new() .spacing(5) .push( - text(format!(" {}", seq)).small().style(color::WARNING), + text(format!(" {}", seq)) + .small() + .style(color::legacy::WARNING), + ) + .push( + icon::hourglass_icon() + .small() + .style(color::legacy::WARNING), ) - .push(icon::hourglass_icon().small().style(color::WARNING)) .align_items(Alignment::Center), )) } else { @@ -254,8 +264,8 @@ fn coin_list_view<'a>( ) .padding(10) .on_press(Message::CreateSpend(CreateSpendMessage::SelectCoin(i))) - .style(button::Style::TransparentBorder.into()), + .style(theme::Button::TransparentBorder), ) - .style(card::SimpleCardStyle) + .style(theme::Container::Card(theme::Card::Simple)) .into() } diff --git a/gui/src/app/view/util.rs b/gui/src/app/view/util.rs index 7f2c9960..94030b9c 100644 --- a/gui/src/app/view/util.rs +++ b/gui/src/app/view/util.rs @@ -1,7 +1,6 @@ -use iced::{widget::Row, Element}; use liana::miniscript::bitcoin::Amount; -use crate::ui::{color, component::text::*, util::Collection}; +use liana_ui::{color, component::text::*, util::Collection, widget::*}; pub fn amount<'a, T: 'a>(a: &Amount) -> impl Into> { amount_with_size(a, TEXT_REGULAR_SIZE) diff --git a/gui/src/app/view/warning.rs b/gui/src/app/view/warning.rs index c4bb5b3f..2e4d61c4 100644 --- a/gui/src/app/view/warning.rs +++ b/gui/src/app/view/warning.rs @@ -1,14 +1,12 @@ use std::convert::From; -use iced::{ - widget::{self, Column, Container}, - Length, -}; +use iced::Length; + +use liana_ui::{component::notification, widget::*}; use crate::{ app::error::Error, daemon::{client::error::RpcErrorCode, DaemonError}, - ui::component::notification, }; /// Simple warning message displayed to non technical user. @@ -48,7 +46,7 @@ impl std::fmt::Display for WarningMessage { } } -pub fn warn<'a, T: 'a + Clone>(error: Option<&Error>) -> widget::Container<'a, T> { +pub fn warn<'a, T: 'a + Clone>(error: Option<&Error>) -> Container<'a, T> { if let Some(w) = error { let message: WarningMessage = w.into(); notification::warning(message.to_string(), w.to_string()).width(Length::Fill) diff --git a/gui/src/installer/mod.rs b/gui/src/installer/mod.rs index 76f57c16..153a43bc 100644 --- a/gui/src/installer/mod.rs +++ b/gui/src/installer/mod.rs @@ -4,8 +4,9 @@ mod prompt; mod step; mod view; -use iced::{clipboard, Command, Element, Subscription}; +use iced::{clipboard, Command, Subscription}; use liana::miniscript::bitcoin; +use liana_ui::widget::Element; use tracing::{error, info, warn}; use context::Context; diff --git a/gui/src/installer/step/descriptor.rs b/gui/src/installer/step/descriptor.rs index 82664370..77aa9570 100644 --- a/gui/src/installer/step/descriptor.rs +++ b/gui/src/installer/step/descriptor.rs @@ -3,7 +3,7 @@ use std::path::PathBuf; use std::str::FromStr; use std::sync::Arc; -use iced::{Command, Element}; +use iced::Command; use liana::{ descriptors::{LianaDescKeys, MultipathDescriptor}, miniscript::{ @@ -17,6 +17,11 @@ use liana::{ }, }; +use liana_ui::{ + component::{form, modal::Modal}, + widget::Element, +}; + use async_hwi::DeviceKind; use crate::{ @@ -28,7 +33,6 @@ use crate::{ view, Error, }, signer::Signer, - ui::component::{form, modal::Modal}, }; pub trait DescriptorKeyModal { diff --git a/gui/src/installer/step/mnemonic.rs b/gui/src/installer/step/mnemonic.rs index 5f88bea9..6cd0f23a 100644 --- a/gui/src/installer/step/mnemonic.rs +++ b/gui/src/installer/step/mnemonic.rs @@ -1,9 +1,11 @@ use std::collections::HashSet; use std::sync::Arc; -use iced::{Command, Element}; +use iced::Command; use liana::{bip39, signer::HotSigner}; +use liana_ui::widget::Element; + use crate::{ installer::{context::Context, message::Message, step::Step, view}, signer::Signer, diff --git a/gui/src/installer/step/mod.rs b/gui/src/installer/step/mod.rs index d1119ffa..560ba16e 100644 --- a/gui/src/installer/step/mod.rs +++ b/gui/src/installer/step/mod.rs @@ -10,10 +10,10 @@ pub use mnemonic::{BackupMnemonic, RecoverMnemonic}; use std::path::PathBuf; use std::str::FromStr; -use iced::{Command, Element}; +use iced::Command; use liana::{config::BitcoindConfig, miniscript::bitcoin}; -use crate::ui::component::form; +use liana_ui::{component::form, widget::*}; use crate::installer::{ context::Context, diff --git a/gui/src/installer/view.rs b/gui/src/installer/view.rs index a19c9411..2721fe18 100644 --- a/gui/src/installer/view.rs +++ b/gui/src/installer/view.rs @@ -1,12 +1,22 @@ use iced::widget::{ - scrollable::Properties, Button, Checkbox, Column, Container, PickList, Row, Scrollable, Space, - TextInput, + checkbox, container, pick_list, scrollable, scrollable::Properties, Space, TextInput, }; -use iced::{alignment, Alignment, Element, Length}; +use iced::{alignment, Alignment, Length}; use std::collections::HashSet; use liana::miniscript::bitcoin; +use liana_ui::{ + color, + component::{ + button, card, collapse, form, separation, + text::{text, Text}, + tooltip, + }, + icon, theme, + util::Collection, + widget::*, +}; use crate::{ hw::HardwareWallet, @@ -15,16 +25,6 @@ use crate::{ message::{self, Message}, prompt, Error, }, - ui::{ - color, - component::{ - button, card, collapse, container, form, separation, - text::{text, Text}, - tooltip, - }, - icon, - util::Collection, - }, }; #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -92,7 +92,7 @@ pub fn welcome<'a>() -> Element<'a, Message> { ) .padding(20), ) - .style(button::Style::Border.into()) + .style(theme::Button::Secondary) .on_press(Message::CreateWallet), ) .push( @@ -106,7 +106,7 @@ pub fn welcome<'a>() -> Element<'a, Message> { ) .padding(20), ) - .style(button::Style::Border.into()) + .style(theme::Button::Secondary) .on_press(Message::ParticipateWallet), ) .push( @@ -120,7 +120,7 @@ pub fn welcome<'a>() -> Element<'a, Message> { ) .padding(20), ) - .style(button::Style::Border.into()) + .style(theme::Button::Secondary) .on_press(Message::ImportWallet), ), ) @@ -153,10 +153,11 @@ pub fn define_descriptor<'a>( .spacing(10) .align_items(Alignment::Center) .push(text("Network:").bold()) - .push(Container::new( - PickList::new(&NETWORKS[..], Some(Network::from(network)), |net| { + .push(container( + pick_list(&NETWORKS[..], Some(Network::from(network)), |net| { Message::Network(net.into()) }) + .style(theme::PickList::Simple) .padding(10), )) .push_maybe(if network_valid { @@ -195,7 +196,7 @@ pub fn define_descriptor<'a>( None }) .push( - Scrollable::new( + scrollable( Row::new() .spacing(5) .align_items(Alignment::Center) @@ -210,7 +211,7 @@ pub fn define_descriptor<'a>( ) .width(Length::Units(200)) .height(Length::Units(200)) - .style(button::Style::TransparentBorder.into()) + .style(theme::Button::TransparentBorder) .on_press( Message::DefineDescriptor( message::DefineDescriptor::AddKey(false), @@ -252,7 +253,7 @@ pub fn define_descriptor<'a>( None }) .push( - Scrollable::new( + scrollable( Row::new() .spacing(5) .align_items(Alignment::Center) @@ -267,7 +268,7 @@ pub fn define_descriptor<'a>( ) .width(Length::Units(200)) .height(Length::Units(200)) - .style(button::Style::TransparentBorder.into()) + .style(theme::Button::TransparentBorder) .on_press( Message::DefineDescriptor( message::DefineDescriptor::AddKey(true), @@ -359,7 +360,7 @@ pub fn import_descriptor<'a>( .align_items(Alignment::Center) .push(text("Network:").bold()) .push(Container::new( - PickList::new(&NETWORKS[..], Some(Network::from(network)), |net| { + pick_list(&NETWORKS[..], Some(Network::from(network)), |net| { Message::Network(net.into()) }) .padding(10), @@ -430,7 +431,7 @@ pub fn signer_xpubs(xpubs: &Vec) -> Element { ) .on_press(Message::UseHotSigner) .padding(10) - .style(button::Style::TransparentBorder.into()) + .style(theme::Button::TransparentBorder) .width(Length::Fill), ) .push_maybe(if xpubs.is_empty() { @@ -448,7 +449,7 @@ pub fn signer_xpubs(xpubs: &Vec) -> Element { .align_items(Alignment::Center) .push( Container::new( - Scrollable::new(Container::new(text(xpub).small()).padding(10)) + scrollable(Container::new(text(xpub).small()).padding(10)) .horizontal_scroll( Properties::new().width(2).scroller_width(2), ), @@ -478,7 +479,7 @@ pub fn signer_xpubs(xpubs: &Vec) -> Element { None }), ) - .style(card::SimpleCardStyle) + .style(theme::Container::Card(theme::Card::Simple)) .into() } @@ -523,7 +524,7 @@ pub fn hardware_wallet_xpubs<'a>( message, iced::widget::tooltip::Position::Bottom, ) - .style(card::SimpleCardStyle), + .style(theme::Container::Card(theme::Card::Simple)), ), }) .spacing(5) @@ -534,16 +535,16 @@ pub fn hardware_wallet_xpubs<'a>( Row::new() .spacing(5) .align_items(Alignment::Center) - .push(icon::warning_icon().style(color::ALERT)) - .push(text("An error occured").style(color::ALERT)), + .push(icon::warning_icon().style(color::legacy::ALERT)) + .push(text("An error occured").style(color::legacy::ALERT)), e, iced::widget::tooltip::Position::Bottom, ) - .style(card::ErrorCardStyle) + .style(theme::Container::Card(theme::Card::Error)) })), ) .padding(10) - .style(button::Style::TransparentBorder.into()) + .style(theme::Button::TransparentBorder) .width(Length::Fill); if !processing && hw.is_supported() { bttn = bttn.on_press(Message::Select(i)); @@ -566,7 +567,7 @@ pub fn hardware_wallet_xpubs<'a>( .align_items(Alignment::Center) .push( Container::new( - Scrollable::new(Container::new(text(xpub).small()).padding(10)) + scrollable(Container::new(text(xpub).small()).padding(10)) .horizontal_scroll( Properties::new().width(2).scroller_width(2), ), @@ -598,7 +599,7 @@ pub fn hardware_wallet_xpubs<'a>( None }), ) - .style(card::SimpleCardStyle) + .style(theme::Container::Card(theme::Card::Simple)) .into() } @@ -615,7 +616,7 @@ pub fn participate_xpub<'a>( .align_items(Alignment::Center) .push(text("Network:").bold()) .push(Container::new( - PickList::new(&NETWORKS[..], Some(Network::from(network)), |net| { + pick_list(&NETWORKS[..], Some(Network::from(network)), |net| { Message::Network(net.into()) }) .padding(10), @@ -658,7 +659,7 @@ pub fn participate_xpub<'a>( .push(signer) .width(Length::Fill), ) - .push(Checkbox::new( + .push(checkbox( "I have shared my public keys", shared, Message::UserActionDone, @@ -744,7 +745,7 @@ pub fn register_descriptor<'a>( ) .width(Length::Fill), ) - .push(Checkbox::new( + .push(checkbox( "I have registered the descriptor on my device(s)", done, Message::UserActionDone, @@ -789,7 +790,7 @@ pub fn backup_descriptor<'a>( .push(text("Learn more").small().bold()) .push(icon::collapse_icon()), ) - .style(button::Style::Transparent.into()) + .style(theme::Button::Transparent) }, || { Button::new( @@ -799,7 +800,7 @@ pub fn backup_descriptor<'a>( .push(text("Learn more").small().bold()) .push(icon::collapsed_icon()), ) - .style(button::Style::Transparent.into()) + .style(theme::Button::Transparent) }, help_backup, )) @@ -818,7 +819,7 @@ pub fn backup_descriptor<'a>( .spacing(10) .max_width(1000), )) - .push(Checkbox::new( + .push(checkbox( "I have backed up my descriptor", done, Message::UserActionDone, @@ -1051,7 +1052,7 @@ pub fn undefined_descriptor_key<'a>() -> Element<'a, message::DefineKey> { .push(Space::with_width(Length::Fill)) .push( Button::new(icon::cross_icon()) - .style(button::Style::Transparent.into()) + .style(theme::Button::Transparent) .on_press(message::DefineKey::Delete), ), ) @@ -1061,7 +1062,7 @@ pub fn undefined_descriptor_key<'a>() -> Element<'a, message::DefineKey> { .spacing(15) .align_items(Alignment::Center) .push( - Scrollable::new( + scrollable( icon::key_icon() .style(color::DARK_GREY) .size(50) @@ -1069,7 +1070,11 @@ pub fn undefined_descriptor_key<'a>() -> Element<'a, message::DefineKey> { ) .horizontal_scroll(Properties::new().width(2).scroller_width(2)), ) - .push(icon::circle_check_icon().style(color::FOREGROUND).size(50)), + .push( + icon::circle_check_icon() + .style(color::legacy::FOREGROUND) + .size(50), + ), ) .height(Length::Fill) .align_y(alignment::Vertical::Center), @@ -1100,7 +1105,7 @@ pub fn defined_descriptor_key( .push(Space::with_width(Length::Fill)) .push( Button::new(icon::cross_icon()) - .style(button::Style::Transparent.into()) + .style(theme::Button::Transparent) .on_press(message::DefineKey::Delete), ), ) @@ -1114,13 +1119,13 @@ pub fn defined_descriptor_key( .spacing(15) .align_items(Alignment::Center) .push( - Scrollable::new(text(name).bold()).horizontal_scroll( + scrollable(text(name).bold()).horizontal_scroll( Properties::new().width(2).scroller_width(2), ), ) .push( icon::circle_check_icon() - .style(color::SUCCESS) + .style(color::legacy::SUCCESS) .size(40) .width(Length::Units(50)), ), @@ -1145,7 +1150,7 @@ pub fn defined_descriptor_key( .push( text("Key is for a different network") .small() - .style(color::ALERT), + .style(color::legacy::ALERT), ) .into() } else if duplicate_key { @@ -1157,7 +1162,7 @@ pub fn defined_descriptor_key( .height(Length::Units(200)) .width(Length::Units(200)), ) - .push(text("Duplicate key").small().style(color::ALERT)) + .push(text("Duplicate key").small().style(color::legacy::ALERT)) .into() } else if duplicate_name { Column::new() @@ -1168,7 +1173,7 @@ pub fn defined_descriptor_key( .height(Length::Units(200)) .width(Length::Units(200)), ) - .push(text("Duplicate name").small().style(color::ALERT)) + .push(text("Duplicate name").small().style(color::legacy::ALERT)) .into() } else { card::simple(col) @@ -1243,7 +1248,7 @@ pub fn edit_key_modal<'a>( .width(Length::Fill), ) .push_maybe(if chosen_signer { - Some(icon::circle_check_icon().style(color::SUCCESS)) + Some(icon::circle_check_icon().style(color::legacy::SUCCESS)) } else { None }) @@ -1251,7 +1256,7 @@ pub fn edit_key_modal<'a>( ) .width(Length::Fill) .on_press(Message::UseHotSigner) - .style(button::Style::Border.into()), + .style(theme::Button::Secondary), ) .width(Length::Fill), ) @@ -1382,7 +1387,7 @@ fn hw_list_view( message, iced::widget::tooltip::Position::Bottom, ) - .style(card::SimpleCardStyle), + .style(theme::Container::Card(theme::Card::Simple)), ), }) .spacing(5) @@ -1398,7 +1403,7 @@ fn hw_list_view( None }) .push_maybe(if registered { - Some(Column::new().push(icon::circle_check_icon().style(color::SUCCESS))) + Some(Column::new().push(icon::circle_check_icon().style(color::legacy::SUCCESS))) } else { None }) @@ -1406,14 +1411,14 @@ fn hw_list_view( .width(Length::Fill), ) .padding(10) - .style(button::Style::TransparentBorder.into()) + .style(theme::Button::TransparentBorder) .width(Length::Fill); if !processing && hw.is_supported() { bttn = bttn.on_press(Message::Select(i)); } Container::new(bttn) .width(Length::Fill) - .style(card::SimpleCardStyle) + .style(theme::Container::Card(theme::Card::Simple)) .into() } @@ -1443,7 +1448,7 @@ pub fn backup_mnemonic<'a>( ) }), ) - .push(Checkbox::new( + .push(checkbox( "I have backed up my mnemonic", done, Message::UserActionDone, @@ -1485,7 +1490,7 @@ pub fn recover_mnemonic<'a>( suggestions.iter().fold(Row::new().spacing(5), |row, sugg| { row.push( Button::new(text(sugg)) - .style(button::Style::Border.into()) + .style(theme::Button::Secondary) .on_press(Message::MnemonicWord( current, sugg.to_string(), @@ -1516,7 +1521,10 @@ pub fn recover_mnemonic<'a>( .width(Length::Units(100)), ) .push_maybe(if *valid { - Some(icon::circle_check_icon().style(color::SUCCESS)) + Some( + icon::circle_check_icon() + .style(color::legacy::SUCCESS), + ) } else { None }), @@ -1524,7 +1532,9 @@ pub fn recover_mnemonic<'a>( }, )) .push(Space::with_height(Length::Units(50))) - .push_maybe(error.map(|e| card::invalid(text(e).style(color::ALERT)))), + .push_maybe( + error.map(|e| card::invalid(text(e).style(color::legacy::ALERT))), + ), ) } else { None @@ -1572,7 +1582,7 @@ fn layout<'a>( progress: (usize, usize), content: impl Into>, ) -> Element<'a, Message> { - Container::new(Scrollable::new( + Container::new(scrollable( Column::new() .push( Container::new(button::transparent(None, "< Previous").on_press(Message::Previous)) @@ -1588,19 +1598,15 @@ fn layout<'a>( .center_x() .height(Length::Fill) .width(Length::Fill) - .style(container::Style::Background) + .style(theme::Container::Background) .into() } mod threshsold_input { - use crate::ui::{ - component::{button, text::*}, - icon, - }; use iced::alignment::{self, Alignment}; - use iced::widget::{Button, Column, Container}; - use iced::{Element, Length}; + use iced::Length; use iced_lazy::{self, Component}; + use liana_ui::{component::text::*, icon, theme, widget::*}; pub struct ThresholdInput { value: usize, @@ -1636,7 +1642,7 @@ mod threshsold_input { } } - impl Component for ThresholdInput { + impl Component> for ThresholdInput { type State = (); type Event = Event; @@ -1662,7 +1668,7 @@ mod threshsold_input { fn view(&self, _state: &Self::State) -> Element { let button = |label, on_press| { Button::new(label) - .style(button::Style::Transparent.into()) + .style(theme::Button::Transparent) .width(Length::Units(50)) .on_press(on_press) }; diff --git a/gui/src/launcher.rs b/gui/src/launcher.rs index 74ab36bf..d92452ab 100644 --- a/gui/src/launcher.rs +++ b/gui/src/launcher.rs @@ -1,21 +1,17 @@ use std::path::PathBuf; -use iced::{ - widget::{Button, Column, Container, Row}, - Alignment, Command, Element, Length, Subscription, -}; +use iced::{Alignment, Command, Length, Subscription}; use liana::{config::ConfigError, miniscript::bitcoin::Network}; - -use crate::{ - app, - ui::{ - component::{badge, button, card, text::*}, - icon, - util::*, - }, +use liana_ui::{ + component::{badge, card, text::*}, + icon, theme, + util::*, + widget::*, }; +use crate::app; + pub struct Launcher { choices: Vec, datadir_path: PathBuf, @@ -102,9 +98,9 @@ impl Launcher { badge::Badge::new(icon::bitcoin_icon()).style( match choice { Network::Bitcoin => { - badge::Style::Bitcoin + theme::Badge::Bitcoin } - _ => badge::Style::Standard, + _ => theme::Badge::Standard, }, ), ) @@ -118,7 +114,7 @@ impl Launcher { .on_press(ViewMessage::Check(*choice)) .padding(10) .width(Length::Fill) - .style(button::Style::Border.into()), + .style(theme::Button::Secondary), ) }, ) @@ -133,7 +129,7 @@ impl Launcher { .on_press(ViewMessage::StartInstall) .padding(10) .width(Length::Fill) - .style(button::Style::TransparentBorder.into()), + .style(theme::Button::TransparentBorder), ), ) .max_width(500) diff --git a/gui/src/lib.rs b/gui/src/lib.rs index 782fcf10..65c34e9c 100644 --- a/gui/src/lib.rs +++ b/gui/src/lib.rs @@ -6,7 +6,6 @@ pub mod launcher; pub mod loader; pub mod logger; pub mod signer; -pub mod ui; pub mod utils; use liana::Version; diff --git a/gui/src/loader.rs b/gui/src/loader.rs index 2c8bb2ec..ed95c998 100644 --- a/gui/src/loader.rs +++ b/gui/src/loader.rs @@ -3,10 +3,6 @@ use std::io::ErrorKind; use std::path::{Path, PathBuf}; use std::sync::Arc; -use iced::{ - widget::{Column, Container, ProgressBar, Row}, - Element, -}; use iced::{Alignment, Command, Length, Subscription}; use tracing::{debug, info}; @@ -15,6 +11,12 @@ use liana::{ miniscript::bitcoin, StartupError, }; +use liana_ui::{ + component::{button, notification, text::*}, + icon, + util::Collection, + widget::*, +}; use crate::{ app::{ @@ -23,11 +25,6 @@ use crate::{ wallet::{Wallet, WalletError}, }, daemon::{client, embedded::EmbeddedDaemon, model::*, Daemon, DaemonError}, - ui::{ - component::{button, notification, text::*}, - icon, - util::Collection, - }, }; type Lianad = client::Lianad; diff --git a/gui/src/main.rs b/gui/src/main.rs index 55c84cdc..5a16e8e6 100644 --- a/gui/src/main.rs +++ b/gui/src/main.rs @@ -2,13 +2,14 @@ use std::{error::Error, io::Write, path::PathBuf, str::FromStr}; -use iced::{executor, Application, Command, Element, Settings, Subscription}; +use iced::{executor, Application, Command, Settings, Subscription}; use tracing::{error, info}; use tracing_subscriber::filter::LevelFilter; extern crate serde; extern crate serde_json; use liana::{config::Config as DaemonConfig, miniscript::bitcoin}; +use liana_ui::{theme, widget::Element}; use liana_gui::{ app::{ @@ -87,7 +88,7 @@ impl Application for GUI { type Executor = executor::Default; type Message = Message; type Flags = Config; - type Theme = iced::Theme; + type Theme = theme::Theme; fn title(&self) -> String { match self.state { diff --git a/gui/src/ui/color.rs b/gui/src/ui/color.rs deleted file mode 100644 index 3e87a13a..00000000 --- a/gui/src/ui/color.rs +++ /dev/null @@ -1,81 +0,0 @@ -use iced::Color; - -pub const BACKGROUND: Color = Color::from_rgb( - 0xF6 as f32 / 255.0, - 0xF7 as f32 / 255.0, - 0xF8 as f32 / 255.0, -); - -pub const BORDER_GREY: Color = Color::from_rgb( - 0xd0 as f32 / 255.0, - 0xd7 as f32 / 255.0, - 0xde as f32 / 255.0, -); - -pub const FOREGROUND: Color = Color::WHITE; - -pub const PRIMARY: Color = Color::BLACK; - -pub const SECONDARY: Color = DARK_GREY; - -pub const SUCCESS: Color = Color::from_rgb( - 0x29 as f32 / 255.0, - 0xBC as f32 / 255.0, - 0x97 as f32 / 255.0, -); - -#[allow(dead_code)] -pub const SUCCESS_LIGHT: Color = Color::from_rgba( - 0x29 as f32 / 255.0, - 0xBC as f32 / 255.0, - 0x97 as f32 / 255.0, - 0.5f32, -); - -pub const ALERT: Color = Color::from_rgb( - 0xF0 as f32 / 255.0, - 0x43 as f32 / 255.0, - 0x59 as f32 / 255.0, -); - -pub const ALERT_LIGHT: Color = Color::from_rgba( - 0xF0 as f32 / 255.0, - 0x43 as f32 / 255.0, - 0x59 as f32 / 255.0, - 0.5f32, -); - -pub const WARNING: Color = - Color::from_rgb(0xFF as f32 / 255.0, 0xa7 as f32 / 255.0, 0x0 as f32 / 255.0); - -pub const WARNING_LIGHT: Color = Color::from_rgba( - 0xFF as f32 / 255.0, - 0xa7 as f32 / 255.0, - 0x0 as f32 / 255.0, - 0.5f32, -); - -pub const CANCEL: Color = Color::from_rgb( - 0x34 as f32 / 255.0, - 0x37 as f32 / 255.0, - 0x3D as f32 / 255.0, -); - -pub const INFO: Color = Color::from_rgb( - 0x2A as f32 / 255.0, - 0x98 as f32 / 255.0, - 0xBD as f32 / 255.0, -); - -pub const INFO_LIGHT: Color = Color::from_rgba( - 0x2A as f32 / 255.0, - 0x98 as f32 / 255.0, - 0xBD as f32 / 255.0, - 0.5f32, -); - -pub const DARK_GREY: Color = Color::from_rgb( - 0x8c as f32 / 255.0, - 0x97 as f32 / 255.0, - 0xa6 as f32 / 255.0, -); diff --git a/gui/src/ui/component/badge.rs b/gui/src/ui/component/badge.rs deleted file mode 100644 index 26ef715b..00000000 --- a/gui/src/ui/component/badge.rs +++ /dev/null @@ -1,209 +0,0 @@ -use iced::{ - widget::{self, tooltip, Container}, - Element, Length, -}; - -use crate::ui::{ - color, - component::{card, text::*}, - icon, -}; - -pub enum Style { - Standard, - Success, - Warning, - Bitcoin, -} - -impl widget::container::StyleSheet for Style { - type Style = iced::Theme; - fn appearance(&self, _style: &Self::Style) -> widget::container::Appearance { - match self { - Self::Standard => widget::container::Appearance { - border_radius: 40.0, - background: color::BACKGROUND.into(), - ..widget::container::Appearance::default() - }, - Self::Success => widget::container::Appearance { - border_radius: 40.0, - background: color::SUCCESS_LIGHT.into(), - text_color: color::SUCCESS.into(), - ..widget::container::Appearance::default() - }, - Self::Warning => widget::container::Appearance { - border_radius: 40.0, - background: color::WARNING_LIGHT.into(), - text_color: color::WARNING.into(), - ..widget::container::Appearance::default() - }, - Self::Bitcoin => widget::container::Appearance { - border_radius: 40.0, - background: color::WARNING.into(), - text_color: iced::Color::WHITE.into(), - ..widget::container::Appearance::default() - }, - } - } -} - -impl From