Преглед на файлове

修复dev模式无法运行的问题

skyffire преди 9 месеца
родител
ревизия
afd2d72951
променени са 2 файла, в които са добавени 112 реда и са изтрити 114 реда
  1. 2 1
      .gitignore
  2. 110 113
      src/main.rs

+ 2 - 1
.gitignore

@@ -3,4 +3,5 @@
 /.vscode
 *.json
 *.log
-/data
+/data
+.idea

+ 110 - 113
src/main.rs

@@ -16,7 +16,7 @@ use tickers_table::TickersTable;
 use layout::{SerializableDashboard, Sidebar};
 use style::{get_icon_text, Icon, ICON_BYTES};
 use screen::{
-    create_button, dashboard, handle_error, Notification, UserTimezone, 
+    create_button, dashboard, handle_error, Notification, UserTimezone,
     dashboard::{Dashboard, pane},
     modal::{confirmation_modal, dashboard_modal}
 };
@@ -29,7 +29,7 @@ use iced::{
     padding, Alignment, Element, Length, Point, Size, Subscription, Task, Theme,
 };
 use iced_futures::MaybeSend;
-use futures::TryFutureExt;
+use futures::{StreamExt, TryFutureExt};
 use std::{collections::HashMap, vec, future::Future};
 
 fn main() {
@@ -164,7 +164,7 @@ impl State {
             Exchange::MARKET_TYPES.iter()
                 .flat_map(|(exchange, market_type)| {
                     tickers_info.insert(*exchange, HashMap::new());
-                    
+
                     let ticksizes_task = match exchange {
                         Exchange::BinanceFutures | Exchange::BinanceSpot => {
                             fetch_ticker_info(*exchange, binance::fetch_ticksize(*market_type))
@@ -286,7 +286,7 @@ impl State {
                     opened_windows.push(self.main_window.id);
 
                     return window::collect_window_specs(
-                        opened_windows, 
+                        opened_windows,
                         Message::SaveAndExit
                     );
                 }
@@ -360,7 +360,7 @@ impl State {
             Message::ErrorOccurred(err) => {
                 return match err {
                     InternalError::Fetch(err) => handle_error(
-                        &err, 
+                        &err,
                         "Failed to fetch data",
                         Message::Notification,
                     ),
@@ -380,13 +380,13 @@ impl State {
                         .map(|&popout_id| window::close(popout_id))
                         .collect::<Vec<_>>(),
                 )
-                .then(|_: Task<window::Id>| Task::none());
+                    .then(|_: Task<window::Id>| Task::none());
 
                 return window_tasks.chain(
                     dashboard
                         .reset_layout()
                         .map(Message::Dashboard)
-                    );
+                );
             }
             Message::LayoutSelected(new_layout_id) => {
                 let active_popout_keys = self
@@ -402,15 +402,15 @@ impl State {
                         .map(|&popout_id| window::close(popout_id))
                         .collect::<Vec<_>>(),
                 )
-                .then(|_: Task<window::Id>| Task::none());
+                    .then(|_: Task<window::Id>| Task::none());
 
                 return window::collect_window_specs(
                     active_popout_keys,
                     dashboard::Message::SavePopoutSpecs,
                 )
-                .map(Message::Dashboard)
-                .chain(window_tasks)
-                .chain(Task::done(Message::LoadLayout(new_layout_id)));
+                    .map(Message::Dashboard)
+                    .chain(window_tasks)
+                    .chain(Task::done(Message::LoadLayout(new_layout_id)));
             }
             Message::LoadLayout(layout_id) => {
                 self.last_active_layout = layout_id;
@@ -452,8 +452,8 @@ impl State {
                 );
 
                 return Task::batch(vec![
-                    bybit_linear_fetch, 
-                    binance_linear_fetch, 
+                    bybit_linear_fetch,
+                    binance_linear_fetch,
                     binance_spot_fetch,
                     bybit_spot_fetch,
                 ]);
@@ -495,7 +495,7 @@ impl State {
                 self.layouts.values_mut().for_each(|dashboard| {
                     dashboard.toggle_trade_fetch(checked, &self.main_window);
                 });
-                    
+
                 if checked {
                     self.confirmation_dialog = None;
                 }
@@ -513,23 +513,23 @@ impl State {
         if id != self.main_window.id {
             return container(
                 dashboard
-                .view_window(
-                    id, 
-                    &self.main_window, 
-                    self.layout_locked,
-                    &self.timezone,
-                )
-                .map(Message::Dashboard)
+                    .view_window(
+                        id,
+                        &self.main_window,
+                        self.layout_locked,
+                        &self.timezone,
+                    )
+                    .map(Message::Dashboard)
             )
-            .padding(padding::top(if cfg!(target_os = "macos") { 20 } else { 0 }))
-            .into();
+                .padding(padding::top(if cfg!(target_os = "macos") { 20 } else { 0 }))
+                .into();
         } else {
             let tooltip_position = if self.sidebar_location == Sidebar::Left {
                 tooltip::Position::Right
             } else {
                 tooltip::Position::Left
             };
-            
+
             let sidebar = {
                 let nav_buttons = {
                     let layout_lock_button = {
@@ -539,13 +539,13 @@ impl State {
                                     Icon::Locked
                                 } else {
                                     Icon::Unlocked
-                                }, 
+                                },
                                 14,
                             ).width(24).align_x(Alignment::Center),
                             Message::ToggleLayoutLock,
                             Some("Layout Lock"),
                             tooltip_position,
-                            |theme: &Theme, status: button::Status| 
+                            |theme: &Theme, status: button::Status|
                                 style::button_transparent(theme, status, false),
                         )
                     };
@@ -570,7 +570,7 @@ impl State {
                     };
                     let layout_modal_button = {
                         let is_active = matches!(self.active_modal, DashboardModal::Layout);
-                
+
                         create_button(
                             get_icon_text(Icon::Layout, 14)
                                 .width(24)
@@ -589,7 +589,7 @@ impl State {
                     };
                     let ticker_search_button = {
                         let is_active = self.show_tickers_dashboard;
-                
+
                         create_button(
                             get_icon_text(Icon::Search, 14)
                                 .width(24)
@@ -610,8 +610,8 @@ impl State {
                         Space::with_height(Length::Fill),
                         settings_modal_button,
                     ]
-                    .width(32)
-                    .spacing(4)
+                        .width(32)
+                        .spacing(4)
                 };
 
                 let tickers_table = {
@@ -621,7 +621,7 @@ impl State {
                                 self.tickers_table.view(size).map(Message::TickersTable)
                             })
                         ]
-                        .width(200)
+                            .width(200)
                     } else {
                         column![]
                     }
@@ -641,12 +641,12 @@ impl State {
                         ]
                     }
                 }
-                .spacing(4)
+                    .spacing(4)
             };
 
             let dashboard_view = dashboard
                 .view(
-                    &self.main_window, 
+                    &self.main_window,
                     self.layout_locked,
                     &self.timezone,
                 )
@@ -697,22 +697,22 @@ impl State {
 
                         let trade_fetch_checkbox = {
                             let is_active = dashboard.trade_fetch_enabled;
-                    
+
                             let checkbox = iced::widget::checkbox("Fetch trades (Binance)", is_active)
                                 .on_toggle(|checked| {
-                                        if checked {
-                                            Message::ToggleDialogModal(
-                                                Some(
-                                                    "This might be unreliable and take some time to complete"
+                                    if checked {
+                                        Message::ToggleDialogModal(
+                                            Some(
+                                                "This might be unreliable and take some time to complete"
                                                     .to_string()
-                                                ),
-                                            )
-                                        } else {
-                                            Message::ToggleTradeFetch(false)
-                                        }
+                                            ),
+                                        )
+                                    } else {
+                                        Message::ToggleTradeFetch(false)
                                     }
+                                }
                                 );
-                    
+
                             tooltip(
                                 checkbox,
                                 Some("Try to fetch trades for footprint charts"),
@@ -722,7 +722,7 @@ impl State {
 
                         let theme_picklist =
                             pick_list(all_themes, Some(self.theme.clone()), Message::ThemeSelected);
-        
+
                         let timezone_picklist = pick_list(
                             [UserTimezone::Utc, UserTimezone::Local],
                             Some(self.timezone),
@@ -748,12 +748,12 @@ impl State {
                                     trade_fetch_checkbox,
                                 ].spacing(4),
                             ]
-                            .spacing(16),
+                                .spacing(16),
                         )
-                        .align_x(Alignment::Start)
-                        .max_width(500)
-                        .padding(24)
-                        .style(style::dashboard_modal)
+                            .align_x(Alignment::Start)
+                            .max_width(500)
+                            .padding(24)
+                            .style(style::dashboard_modal)
                     };
 
                     let (align_x, padding) = match self.sidebar_location {
@@ -783,15 +783,15 @@ impl State {
                                 ]
                                 .spacing(8),
                             ]
-                            .align_x(Alignment::Center)
-                            .spacing(16),
+                                .align_x(Alignment::Center)
+                                .spacing(16),
                         )
-                        .padding(24)
-                        .style(style::dashboard_modal);
-    
+                            .padding(24)
+                            .style(style::dashboard_modal);
+
                         confirmation_modal(
-                            base_content, 
-                            dialog_content, 
+                            base_content,
+                            dialog_content,
                             Message::ToggleDialogModal(None)
                         )
                     } else {
@@ -818,7 +818,7 @@ impl State {
                         Some("Layouts won't be saved if app exited abruptly"),
                         tooltip::Position::Top,
                     );
-    
+
                     // Pane management
                     let reset_pane_button = tooltip(
                         button(text("Reset").align_x(Alignment::Center))
@@ -871,19 +871,19 @@ impl State {
                                 .align_x(Alignment::Center)
                                 .spacing(8),
                             ]
-                            .align_x(Alignment::Center)
-                            .spacing(32),
+                                .align_x(Alignment::Center)
+                                .spacing(32),
                         )
-                        .width(280)
-                        .padding(24)
-                        .style(style::dashboard_modal)
+                            .width(280)
+                            .padding(24)
+                            .style(style::dashboard_modal)
                     };
 
                     let (align_x, padding) = match self.sidebar_location {
                         Sidebar::Left => (Alignment::Start, padding::left(48).top(40)),
                         Sidebar::Right => (Alignment::End, padding::right(48).top(40)),
                     };
-    
+
                     dashboard_modal(
                         base,
                         manage_layout_modal,
@@ -927,26 +927,16 @@ impl State {
                             let ticker: Ticker = *ticker;
 
                             let depth_stream = match exchange {
-                                Exchange::BinanceFutures => Subscription::run_with_id(
-                                    ticker,
-                                    binance::connect_market_stream(ticker),
-                                )
-                                .map(move |event| Message::MarketWsEvent(exchange, event)),
-                                Exchange::BybitLinear => Subscription::run_with_id(
-                                    ticker,
-                                    bybit::connect_market_stream(ticker),
-                                )
-                                .map(move |event| Message::MarketWsEvent(exchange, event)),
-                                Exchange::BinanceSpot => Subscription::run_with_id(
-                                    ticker,
-                                    binance::connect_market_stream(ticker),
-                                )
-                                .map(move |event| Message::MarketWsEvent(exchange, event)),
-                                Exchange::BybitSpot => Subscription::run_with_id(
-                                    ticker,
-                                    bybit::connect_market_stream(ticker),
-                                )
-                                .map(move |event| Message::MarketWsEvent(exchange, event)),
+                                Exchange::BinanceFutures | Exchange::BinanceSpot => {
+                                    let stream = binance::connect_market_stream(ticker)
+                                        .map(move |evt| create_market_event(exchange, evt));
+                                    Subscription::run_with_id(ticker, stream)
+                                },
+                                Exchange::BybitLinear | Exchange::BybitSpot => {
+                                    let stream = bybit::connect_market_stream(ticker)
+                                        .map(move |evt| create_market_event(exchange, evt));
+                                    Subscription::run_with_id(ticker, stream)
+                                },
                             };
                             depth_streams.push(depth_stream);
                         }
@@ -956,27 +946,30 @@ impl State {
                 if !kline_streams.is_empty() {
                     let kline_streams_id: Vec<(Ticker, Timeframe)> = kline_streams.clone();
 
+                    let market_type = match exchange {
+                        Exchange::BinanceFutures | Exchange::BybitLinear => MarketType::LinearPerps,
+                        Exchange::BinanceSpot | Exchange::BybitSpot => MarketType::Spot,
+                    };
+
                     let kline_subscription = match exchange {
-                        Exchange::BinanceFutures => Subscription::run_with_id(
-                            kline_streams_id,
-                            binance::connect_kline_stream(kline_streams, MarketType::LinearPerps),
-                        )
-                        .map(move |event| Message::MarketWsEvent(exchange, event)),
-                        Exchange::BybitLinear => Subscription::run_with_id(
-                            kline_streams_id,
-                            bybit::connect_kline_stream(kline_streams, MarketType::LinearPerps),
-                        )
-                        .map(move |event| Message::MarketWsEvent(exchange, event)),
-                        Exchange::BinanceSpot => Subscription::run_with_id(
-                            kline_streams_id,
-                            binance::connect_kline_stream(kline_streams, MarketType::Spot),
-                        )
-                        .map(move |event| Message::MarketWsEvent(exchange, event)),
-                        Exchange::BybitSpot => Subscription::run_with_id(
-                            kline_streams_id,
-                            bybit::connect_kline_stream(kline_streams, MarketType::Spot),
-                        )
-                        .map(move |event| Message::MarketWsEvent(exchange, event)),
+                        Exchange::BinanceFutures | Exchange::BinanceSpot => {
+                            let stream = binance::connect_kline_stream(
+                                kline_streams,
+                                market_type,
+                            )
+                                .map(move |evt| create_market_event(exchange, evt));
+
+                            Subscription::run_with_id(kline_streams_id, stream)
+                        },
+                        Exchange::BybitLinear | Exchange::BybitSpot => {
+                            let stream = bybit::connect_kline_stream(
+                                kline_streams,
+                                market_type,
+                            )
+                                .map(move |evt| create_market_event(exchange, evt));
+
+                            Subscription::run_with_id(kline_streams_id, stream)
+                        },
                     };
                     market_subscriptions.push(kline_subscription);
                 }
@@ -989,7 +982,7 @@ impl State {
         let tickers_table_fetch = iced::time::every(std::time::Duration::from_secs(
             if self.show_tickers_dashboard { 25 } else { 300 },
         ))
-        .map(|_| Message::FetchAndUpdateTickersTable);
+            .map(|_| Message::FetchAndUpdateTickersTable);
 
         let window_events = window_events().map(Message::WindowEvent);
 
@@ -1009,15 +1002,19 @@ impl State {
     }
 }
 
+fn create_market_event(exchange: Exchange, event: data_providers::Event) -> Message {
+    Message::MarketWsEvent(exchange, event)
+}
+
 fn fetch_ticker_info<F>(exchange: Exchange, fetch_fn: F) -> Task<Message>
 where
     F: Future<
-            Output = Result<
-                HashMap<Ticker, Option<data_providers::TickerInfo>>,
-                data_providers::StreamError,
-            >,
-        > + MaybeSend
-        + 'static,
+        Output = Result<
+            HashMap<Ticker, Option<data_providers::TickerInfo>>,
+            data_providers::StreamError,
+        >,
+    > + MaybeSend
+    + 'static,
 {
     Task::perform(
         fetch_fn.map_err(|err| format!("{err}")),
@@ -1031,8 +1028,8 @@ where
 fn fetch_ticker_prices<F>(exchange: Exchange, fetch_fn: F) -> Task<Message>
 where
     F: Future<Output = Result<HashMap<Ticker, TickerStats>, data_providers::StreamError>>
-        + MaybeSend
-        + 'static,
+    + MaybeSend
+    + 'static,
 {
     Task::perform(
         fetch_fn.map_err(|err| format!("{err}")),