diff --git a/Cargo.lock b/Cargo.lock index d572f29..7580d47 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1342,7 +1342,7 @@ version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef5282ad69563b5fc40319526ba27e0e7363d552a896f0297d54f767717f9b95" dependencies = [ - "litrs", + "litrs 0.4.1", ] [[package]] @@ -2363,6 +2363,15 @@ dependencies = [ "png", ] +[[package]] +name = "include_path" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6259e6c697973f2b71f03a5af7d94ca6de0f1efa96c398c1a2e170952abfd0ca" +dependencies = [ + "litrs 0.2.3", +] + [[package]] name = "indexmap" version = "2.2.6" @@ -2697,6 +2706,15 @@ version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" +[[package]] +name = "litrs" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9275e0933cf8bb20f008924c0cb07a0692fe54d8064996520bf998de9eb79aa" +dependencies = [ + "proc-macro2", +] + [[package]] name = "litrs" version = "0.4.1" @@ -4404,7 +4422,7 @@ dependencies = [ [[package]] name = "thunder" -version = "0.8.8" +version = "0.8.9" dependencies = [ "anyhow", "bincode", @@ -4441,7 +4459,7 @@ dependencies = [ [[package]] name = "thunder_app" -version = "0.8.8" +version = "0.8.9" dependencies = [ "anyhow", "base64 0.21.7", @@ -4453,6 +4471,7 @@ dependencies = [ "eframe", "futures", "human-size", + "include_path", "jsonrpsee", "parking_lot", "poll-promise", @@ -4475,7 +4494,7 @@ dependencies = [ [[package]] name = "thunder_app_cli" -version = "0.8.8" +version = "0.8.9" dependencies = [ "anyhow", "bip300301", @@ -4489,7 +4508,7 @@ dependencies = [ [[package]] name = "thunder_app_rpc_api" -version = "0.8.8" +version = "0.8.9" dependencies = [ "bip300301", "jsonrpsee", diff --git a/Cargo.toml b/Cargo.toml index 8181c4f..45b2092 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,7 @@ authors = [ "Nikita Chashchinskii " ] edition = "2021" -version = "0.8.8" +version = "0.8.9" [workspace.dependencies.bip300301] git = "https://github.com/Ash-L2L/bip300301.git" diff --git a/README.md b/README.md new file mode 100644 index 0000000..fa45123 --- /dev/null +++ b/README.md @@ -0,0 +1,10 @@ +# Thunder + +## Install + +Check out the repo with `git clone`, and then + +``` +git submodule update --init +cargo build +``` \ No newline at end of file diff --git a/app/Cargo.toml b/app/Cargo.toml index 5ec0e04..2dfd09a 100644 --- a/app/Cargo.toml +++ b/app/Cargo.toml @@ -22,6 +22,7 @@ dirs = "5.0.1" eframe = "0.27.1" futures = "0.3.30" human-size = "0.4.3" +include_path = "0.1.1" jsonrpsee = { version = "0.20.0", features = ["server"] } rustreexo = { workspace = true } parking_lot = "0.12.1" diff --git a/app/gui/fonts.rs b/app/gui/fonts.rs new file mode 100644 index 0000000..4162587 --- /dev/null +++ b/app/gui/fonts.rs @@ -0,0 +1,39 @@ +//! Load fonts for egui + +use std::sync::LazyLock; + +use eframe::egui::{FontData, FontDefinitions, FontFamily}; + +static FIRA_MONO_NERD_REGULAR: &[u8] = include_path::include_path_bytes!( + "../../res/nerd-fonts/patched-fonts/FiraMono/Regular/FiraMonoNerdFont-Regular.otf" +); + +static NOTO_SANS_MONO_NERD_REGULAR: &[u8] = include_path::include_path_bytes!( + "../../res/nerd-fonts/patched-fonts/Noto/Sans-Mono/NotoSansMNerdFont-Regular.ttf" +); + +pub static FONT_DEFINITIONS: LazyLock = LazyLock::new(|| { + let mut fonts = FontDefinitions::default(); + // Install fonts + fonts.font_data.insert( + "Fira Mono Nerd Regular".to_owned(), + FontData::from_static(FIRA_MONO_NERD_REGULAR), + ); + fonts.font_data.insert( + "Noto Sans Mono Nerd Regular".to_owned(), + FontData::from_static(NOTO_SANS_MONO_NERD_REGULAR), + ); + // Set Fira Mono Nerd Regular as first monospace font + fonts + .families + .get_mut(&FontFamily::Monospace) + .unwrap() + .insert(0, "Fira Mono Nerd Regular".to_owned()); + // Set Noto Sans Mono Nerd Regular as second monospace font + fonts + .families + .get_mut(&FontFamily::Monospace) + .unwrap() + .insert(1, "Noto Sans Mono Nerd Regular".to_owned()); + fonts +}); diff --git a/app/gui/mod.rs b/app/gui/mod.rs index b2369cb..6896e3b 100644 --- a/app/gui/mod.rs +++ b/app/gui/mod.rs @@ -1,14 +1,16 @@ use std::{net::SocketAddr, task::Poll}; -use eframe::egui; +use eframe::egui::{self, RichText}; use strum::{EnumIter, IntoEnumIterator}; use thunder::{util::Watchable, wallet::Wallet}; +use util::{show_btc_amount_from_sats, BITCOIN_LOGO_FA, BITCOIN_ORANGE}; use crate::{app::App, line_buffer::LineBuffer, util::PromiseStream}; mod block_explorer; mod coins; mod console_logs; +mod fonts; mod mempool_explorer; mod miner; mod parent_chain; @@ -19,6 +21,7 @@ mod withdrawals; use block_explorer::BlockExplorer; use coins::Coins; use console_logs::ConsoleLogs; +use fonts::FONT_DEFINITIONS; use mempool_explorer::MemPoolExplorer; use miner::Miner; use parent_chain::ParentChain; @@ -62,7 +65,7 @@ struct BottomPanel { wallet_updated: PromiseStream<>::WatchStream>, /// None if uninitialized /// Some(None) if failed to initialize - balance: Option>, + balance_sats: Option>, } impl BottomPanel { @@ -71,13 +74,13 @@ impl BottomPanel { let wallet_updated = PromiseStream::from(wallet.watch()); Self { wallet_updated, - balance: None, + balance_sats: None, } } /// Updates values fn update(&mut self, app: &App) { - self.balance = match app.wallet.get_balance() { + self.balance_sats = match app.wallet.get_balance() { Ok(balance) => Some(Some(balance)), Err(err) => { let err = anyhow::Error::from(err); @@ -88,11 +91,18 @@ impl BottomPanel { } fn show_balance(&self, ui: &mut egui::Ui) { - match self.balance { - Some(Some(balance)) => { + match self.balance_sats { + Some(Some(balance_sats)) => { + ui.monospace( + RichText::new(BITCOIN_LOGO_FA.to_string()) + .color(BITCOIN_ORANGE), + ); ui.monospace_selectable_singleline( false, - format!("Balance: {balance}"), + format!( + "Balance: {}", + show_btc_amount_from_sats(balance_sats) + ), ); } Some(None) => { @@ -151,7 +161,7 @@ impl BottomPanel { impl EguiApp { pub fn new( app: App, - _cc: &eframe::CreationContext<'_>, + cc: &eframe::CreationContext<'_>, logs_capture: LineBuffer, rpc_addr: SocketAddr, ) -> Self { @@ -159,6 +169,7 @@ impl EguiApp { // Restore app state using cc.storage (requires the "persistence" feature). // Use the cc.gl (a glow::Context) to create graphics shaders and buffers that you can use // for e.g. egui::PaintCallback. + cc.egui_ctx.set_fonts(FONT_DEFINITIONS.clone()); let rt_guard = app.runtime.enter(); let bottom_panel = BottomPanel::new(&app.wallet); drop(rt_guard); diff --git a/app/gui/util.rs b/app/gui/util.rs index ccc0db8..6fbde2d 100644 --- a/app/gui/util.rs +++ b/app/gui/util.rs @@ -1,6 +1,31 @@ use std::borrow::Borrow; -use eframe::egui::{self, InnerResponse, Response, Ui}; +use bip300301::bitcoin; +use eframe::egui::{self, Color32, InnerResponse, Response, Ui}; + +/// Bitcoin Orange Color +pub const BITCOIN_ORANGE: Color32 = Color32::from_rgb(0xf7, 0x93, 0x1a); + +/// Unicode BTC symbol (U+20BF) +pub const BTC_UNICODE: char = '\u{20bf}'; + +/// Font-Awesome Bitcoin Logo symbol (U+F10F) +/// Note that this symbol is wider than other glyphs, often taking up as much +/// space as 3 chars. +pub const BITCOIN_LOGO_FA: char = '\u{f10f}'; + +/// Show a [`bitcoin::Amount`] +pub fn show_btc_amount(amount: bitcoin::Amount) -> String { + format!( + "{BTC_UNICODE}{}", + amount.to_string_in(bitcoin::Denomination::Bitcoin) + ) +} + +/// Show a Bitcoin amount from sats +pub fn show_btc_amount_from_sats(sats: u64) -> String { + show_btc_amount(bitcoin::Amount::from_sat(sats)) +} // extension for InnerResponse and InnerResponse> pub trait InnerResponseExt { diff --git a/res/nerd-fonts/patched-fonts/FiraMono/Regular/FiraMonoNerdFont-Regular.otf b/res/nerd-fonts/patched-fonts/FiraMono/Regular/FiraMonoNerdFont-Regular.otf new file mode 100644 index 0000000..55a1531 Binary files /dev/null and b/res/nerd-fonts/patched-fonts/FiraMono/Regular/FiraMonoNerdFont-Regular.otf differ diff --git a/res/nerd-fonts/patched-fonts/Noto/Sans-Mono/NotoSansMNerdFont-Regular.ttf b/res/nerd-fonts/patched-fonts/Noto/Sans-Mono/NotoSansMNerdFont-Regular.ttf new file mode 100644 index 0000000..5a07cff Binary files /dev/null and b/res/nerd-fonts/patched-fonts/Noto/Sans-Mono/NotoSansMNerdFont-Regular.ttf differ