use ratatui::style::Color;
use serde::{Deserialize, Serialize};
use std::time::Instant;
pub use scope::config::{
AlertConfig, ColorScheme, DEFAULT_MONITOR_REFRESH_SECS, ExportConfig, LayoutPreset,
MonitorConfig, ScaleMode, WidgetVisibility,
};
pub(crate) const MAX_DATA_AGE_SECS: f64 = 24.0 * 3600.0;
pub(crate) const CACHE_FILE_PREFIX: &str = "bcc_monitor_";
pub(crate) const DEFAULT_REFRESH_SECS: u64 = DEFAULT_MONITOR_REFRESH_SECS;
pub(crate) const MIN_REFRESH_SECS: u64 = 1;
pub(crate) const MAX_REFRESH_SECS: u64 = 60;
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub struct DataPoint {
pub timestamp: f64,
pub value: f64,
pub is_real: bool,
}
#[derive(Debug, Clone, Copy)]
pub struct OhlcCandle {
pub timestamp: f64,
pub open: f64,
pub high: f64,
pub low: f64,
pub close: f64,
pub is_bullish: bool,
}
impl OhlcCandle {
pub fn new(timestamp: f64, price: f64) -> Self {
Self {
timestamp,
open: price,
high: price,
low: price,
close: price,
is_bullish: true,
}
}
pub fn update(&mut self, price: f64) {
self.high = self.high.max(price);
self.low = self.low.min(price);
self.close = price;
self.is_bullish = self.close >= self.open;
}
}
#[derive(Debug, Serialize, Deserialize)]
pub(crate) struct CachedMonitorData {
pub(crate) token_address: String,
pub(crate) chain: String,
pub(crate) price_history: Vec<DataPoint>,
pub(crate) volume_history: Vec<DataPoint>,
pub(crate) saved_at: f64,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TimePeriod {
Min1,
Min5,
Min15,
Hour1,
Hour4,
Day1,
}
impl TimePeriod {
pub fn duration_secs(&self) -> i64 {
match self {
TimePeriod::Min1 => 60,
TimePeriod::Min5 => 5 * 60,
TimePeriod::Min15 => 15 * 60,
TimePeriod::Hour1 => 3600,
TimePeriod::Hour4 => 4 * 3600,
TimePeriod::Day1 => 24 * 3600,
}
}
pub fn label(&self) -> &'static str {
match self {
TimePeriod::Min1 => "1m",
TimePeriod::Min5 => "5m",
TimePeriod::Min15 => "15m",
TimePeriod::Hour1 => "1h",
TimePeriod::Hour4 => "4h",
TimePeriod::Day1 => "1d",
}
}
pub fn index(&self) -> usize {
match self {
TimePeriod::Min1 => 0,
TimePeriod::Min5 => 1,
TimePeriod::Min15 => 2,
TimePeriod::Hour1 => 3,
TimePeriod::Hour4 => 4,
TimePeriod::Day1 => 5,
}
}
pub fn exchange_interval(&self) -> &'static str {
match self {
TimePeriod::Min1 => "1m",
TimePeriod::Min5 => "5m",
TimePeriod::Min15 => "15m",
TimePeriod::Hour1 => "1h",
TimePeriod::Hour4 => "4h",
TimePeriod::Day1 => "1d",
}
}
pub fn next(&self) -> Self {
match self {
TimePeriod::Min1 => TimePeriod::Min5,
TimePeriod::Min5 => TimePeriod::Min15,
TimePeriod::Min15 => TimePeriod::Hour1,
TimePeriod::Hour1 => TimePeriod::Hour4,
TimePeriod::Hour4 => TimePeriod::Day1,
TimePeriod::Day1 => TimePeriod::Min1,
}
}
}
impl std::fmt::Display for TimePeriod {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.label())
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum ChartMode {
#[default]
Line,
Candlestick,
VolumeProfile,
}
impl ChartMode {
pub fn next(&self) -> Self {
match self {
ChartMode::Line => ChartMode::Candlestick,
ChartMode::Candlestick => ChartMode::VolumeProfile,
ChartMode::VolumeProfile => ChartMode::Line,
}
}
pub fn label(&self) -> &'static str {
match self {
ChartMode::Line => "Line",
ChartMode::Candlestick => "Candle",
ChartMode::VolumeProfile => "VolPro",
}
}
}
pub trait ColorSchemeExt {
fn palette(&self) -> ColorPalette;
}
impl ColorSchemeExt for ColorScheme {
fn palette(&self) -> ColorPalette {
match self {
ColorScheme::GreenRed => ColorPalette {
up: Color::Green,
down: Color::Red,
neutral: Color::Gray,
header_fg: Color::White,
border: Color::DarkGray,
highlight: Color::Yellow,
volume_bar: Color::Blue,
sparkline: Color::Cyan,
},
ColorScheme::BlueOrange => ColorPalette {
up: Color::Blue,
down: Color::Rgb(255, 165, 0), neutral: Color::Gray,
header_fg: Color::White,
border: Color::DarkGray,
highlight: Color::Cyan,
volume_bar: Color::Magenta,
sparkline: Color::LightBlue,
},
ColorScheme::Monochrome => ColorPalette {
up: Color::White,
down: Color::DarkGray,
neutral: Color::Gray,
header_fg: Color::White,
border: Color::DarkGray,
highlight: Color::White,
volume_bar: Color::Gray,
sparkline: Color::White,
},
}
}
}
#[derive(Debug, Clone, Copy)]
pub struct ColorPalette {
pub up: Color,
pub down: Color,
pub neutral: Color,
pub header_fg: Color,
pub border: Color,
pub highlight: Color,
pub volume_bar: Color,
pub sparkline: Color,
}
#[derive(Debug, Clone)]
pub struct ActiveAlert {
pub message: String,
pub triggered_at: Instant,
}