diff --git a/assets/Dynasty.app/Contents/Info.plist b/assets/Dynasty.app/Contents/Info.plist new file mode 100644 index 0000000..2bf691c --- /dev/null +++ b/assets/Dynasty.app/Contents/Info.plist @@ -0,0 +1,38 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + dynasty + CFBundleIdentifier + org.x86y.dynasty + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + Dynasty + CFBundlePackageType + APPL + CFBundleShortVersionString + 0.1.0 + CFBundleSupportedPlatforms + + MacOSX + + CFBundleVersion + aae12ff-dirty + CFBundleIconFile + dynasty.icns + NSHighResolutionCapable + + NSMainNibFile + + NSSupportsAutomaticGraphicsSwitching + + CFBundleDisplayName + Halloy + NSRequiresAquaSystemAppearance + NO + + diff --git a/assets/Dynasty.app/Contents/Resources/dynasty.icns b/assets/Dynasty.app/Contents/Resources/dynasty.icns new file mode 100644 index 0000000..bae5b99 Binary files /dev/null and b/assets/Dynasty.app/Contents/Resources/dynasty.icns differ diff --git a/scripts/macos b/scripts/macos index 34783d0..37cbf2c 100755 --- a/scripts/macos +++ b/scripts/macos @@ -1,10 +1,12 @@ #!/bin/bash +# taken from https://github.com/squidowl/halloy/blob/main/scripts/build-macos.sh +# credits to Halloy TARGET="dynasty" ASSETS_DIR="assets" RELEASE_DIR="target/release" APP_NAME="Dynasty.app" -APP_TEMPLATE="$ASSETS_DIR/macos/$APP_NAME" +APP_TEMPLATE="$ASSETS_DIR/$APP_NAME" APP_TEMPLATE_PLIST="$APP_TEMPLATE/Contents/Info.plist" APP_DIR="$RELEASE_DIR/macos" APP_BINARY="$RELEASE_DIR/$TARGET" diff --git a/src/config.rs b/src/config.rs index af9f3e7..3f6f8f8 100644 --- a/src/config.rs +++ b/src/config.rs @@ -64,7 +64,7 @@ impl Config { .await .map_err(|_| SaveError::Write)?; } - tokio::time::sleep(std::time::Duration::from_secs(2)).await; + //tokio::time::sleep(std::time::Duration::from_secs(2)).await; Ok(()) } } diff --git a/src/main.rs b/src/main.rs index 265ba26..ecbcab1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,7 +4,6 @@ mod theme; mod views; mod ws; -use binance::api::Binance; use binance::rest_model::OrderStatus; use binance::ws_model::TradesEvent; use config::Config; @@ -23,6 +22,7 @@ use std::collections::BTreeMap; use std::collections::HashMap; use std::collections::VecDeque; use std::env; +use views::panes::orders::tb; use views::panes::style; use views::panes::view_controls; use views::panes::Pane; @@ -219,7 +219,10 @@ impl Application for App { fn update(&mut self, message: Message) -> Command { match message { - Message::Saved(_) => Command::none(), + Message::Saved(_) => { + self.current_view = ViewState::Dashboard; + Command::none() + } Message::SaveConfig(pub_k, sec_k) => Command::perform( Config { api_key: pub_k, @@ -561,7 +564,7 @@ impl Application for App { let focus = self.focus; let total_panes = self.panes.len(); - let pane_grid = PaneGrid::new(&self.panes, |id, pane, is_maximized| { + let dashboard_grid = PaneGrid::new(&self.panes, |id, pane, is_maximized| { let is_focused = focus == Some(id); let title = row![text(pane.id.to_string()).style(if is_focused { @@ -590,7 +593,7 @@ impl Application for App { PaneType::Book => book_view(&self.data.book), PaneType::Trades => trades_view(&self.data.trades), PaneType::Market => market_view(&self.new_price, &self.new_amt, &self.new_pair), - PaneType::Balances => balances_view(&self.data.balances, &self.data.prices), + PaneType::Balances => balances_view(&self.data.balances), PaneType::Orders => orders_view(&self.data.orders, &self.data.prices), })) .title_bar(title_bar) @@ -607,36 +610,47 @@ impl Application for App { .on_drag(Message::Dragged) .on_resize(10, Message::Resized); - let header = row![ - Row::with_children( - self.watchlist_favorites - .iter() - .map(|t| { - let price_now = self.data.prices.get(t).unwrap_or(&0.0); - let ticker = t.split("USDT").next().unwrap(); - let handle = svg::Handle::from_path(format!( - "{}/assets/logos/{}.svg", - env!("CARGO_MANIFEST_DIR"), - ticker - )); - - let svg = svg(handle) - .width(Length::Fixed(16.0)) - .height(Length::Fixed(16.0)); - return row![svg, text(format!("{:.2}", price_now))] - .spacing(4) - .align_items(iced::Alignment::Center); - }) - .map(Element::from) - ) - .spacing(12), - Space::new(Length::Fill, 1), - button("Settings") - .padding(8) - .style(iced::theme::Button::Text) - .on_press(Message::SetSettingsView) - ] - .align_items(iced::Alignment::Center); + let header = container( + row![ + Row::with_children( + self.watchlist_favorites + .iter() + .map(|t| { + let price_now = self.data.prices.get(t).unwrap_or(&0.0); + let ticker = t.split("USDT").next().unwrap(); + let handle = svg::Handle::from_path(format!( + "{}/assets/logos/{}.svg", + env!("CARGO_MANIFEST_DIR"), + ticker + )); + + let svg = svg(handle) + .width(Length::Fixed(16.0)) + .height(Length::Fixed(16.0)); + return row![svg, text(format!("{:.2}", price_now)).size(14)] + .spacing(4) + .align_items(iced::Alignment::Center); + }) + .map(Element::from) + ) + .spacing(12), + Space::new(Length::Fill, 1), + button(text("Settings").size(14)) + .padding(8) + .style(iced::theme::Button::Text) + .on_press(Message::SetSettingsView) + ] + .align_items(iced::Alignment::Center), + ) + .padding([0, 16]) + .style(container::Appearance { + background: Some(iced::Background::Color(Color::from_rgb(0.07, 0.07, 0.07))), + border: iced::Border { + radius: 16.0.into(), + ..Default::default() + }, + ..Default::default() + }); let api_key_input = text_input("API Key", &self.config.api_key) .secure(true) @@ -655,15 +669,25 @@ impl Application for App { api_secret_key_input, ] .spacing(10), - button("SAVE!").on_press(Message::SaveConfig( + button(tb("Save")).on_press(Message::SaveConfig( self.config.api_key.clone(), self.config.api_secret_key.clone() )), ] .spacing(10) + .padding(20) .width(Length::Fill) + .height(Length::Fill) .align_items(iced::Alignment::Center), ) + .style(container::Appearance { + background: Some(iced::Background::Color(Color::from_rgb(0.07, 0.07, 0.07))), + border: iced::Border { + radius: 16.0.into(), + ..Default::default() + }, + ..Default::default() + }) .center_x() .center_y(); @@ -678,10 +702,13 @@ impl Application for App { column![container( column![ header, - if self.current_view == ViewState::Dashboard { - container(pane_grid) + if self.current_view == ViewState::Dashboard + && !self.config.api_key.is_empty() + && !self.config.api_secret_key.is_empty() + { + container(dashboard_grid) } else { - container(column![settings].width(Length::Fill).height(Length::Fill)) + container(settings) } ] .spacing(8) diff --git a/src/views/panes/balances.rs b/src/views/panes/balances.rs index 058d237..2de315c 100644 --- a/src/views/panes/balances.rs +++ b/src/views/panes/balances.rs @@ -1,4 +1,3 @@ -use std::collections::HashMap; use binance::rest_model::Balance; use iced::{ @@ -10,7 +9,7 @@ use crate::{theme::h2c, Message}; use crate::views::components::unstyled_btn::UnstyledBtn; -pub fn balances_view<'a>(bs: &[Balance], ps: &'a HashMap) -> Element<'a, Message> { +pub fn balances_view<'a>(bs: &[Balance]) -> Element<'a, Message> { scrollable( Column::with_children( bs.iter() diff --git a/src/views/panes/market.rs b/src/views/panes/market.rs index ac76d57..00f732e 100644 --- a/src/views/panes/market.rs +++ b/src/views/panes/market.rs @@ -1,5 +1,6 @@ use crate::views::components::better_btn::{GreenBtn, RedBtn}; use crate::views::components::input::Inp; +use iced::Font; use iced::{ widget::{button, column, container, row, text, text_input, Space}, Alignment, Element, Length, @@ -7,6 +8,8 @@ use iced::{ use crate::Message; +use super::orders::t; + macro_rules! bbtn { ($e: expr) => { button($e).style(iced::theme::Button::Text).padding(8) @@ -58,15 +61,29 @@ pub fn market_view<'a>(quote: &str, amt: &str, pair: &str) -> Element<'a, Messag .spacing(4.0) .width(350.0), row![ - button("BUY") - .style(iced::theme::Button::Custom(Box::new(GreenBtn {}))) - .padding(8) - .on_press(Message::BuyPressed), + button( + t("Buy") + .font(Font { + weight: iced::font::Weight::Bold, + ..Default::default() + }) + .size(12) + ) + .style(iced::theme::Button::Custom(Box::new(GreenBtn {}))) + .padding(8) + .on_press(Message::BuyPressed), Space::new(5.0, 0.0), - button("Sell") - .style(iced::theme::Button::Custom(Box::new(RedBtn {}))) - .padding(8) - .on_press(Message::SellPressed) + button( + t("Sell") + .font(Font { + weight: iced::font::Weight::Bold, + ..Default::default() + }) + .size(12) + ) + .style(iced::theme::Button::Custom(Box::new(RedBtn {}))) + .padding(8) + .on_press(Message::SellPressed) ], Space::new(Length::Fill, 1.0) ]