Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wallet balance history logic #31

Merged
merged 2 commits into from
Dec 13, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions crates/core/src/theme/text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@ use iced::widget::text;
impl text::StyleSheet for Theme {
type Style = iced_style::theme::Text;

// TODO extend the color palette to support text colors
fn appearance(&self, style: Self::Style) -> text::Appearance {
//text::Appearance {
// color: Some(self.palette.text.primary),
//}
// text::Appearance {
// color: Some(self.palette.bright.surface),
// }
Default::default()
}
}
20 changes: 12 additions & 8 deletions src/gui/element/wallet/operation/chart.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ impl Chart<Message> for BalanceChart {
(chart_color.b * 255.0) as u8,
);

let date_color = self.theme.palette.bright.secondary;
let date_color = self.theme.palette.normal.surface;
let date_color = RGBColor(
(date_color.r * 255.0) as u8,
(date_color.g * 255.0) as u8,
Expand All @@ -190,6 +190,13 @@ impl Chart<Message> for BalanceChart {
(background_color.b * 255.0) as u8,
);

let text_color = self.theme.palette.bright.surface;
let text_color = RGBColor(
(text_color.r * 255.0) as u8,
(text_color.g * 255.0) as u8,
(text_color.b * 255.0) as u8,
);

chart
.configure_mesh()
.bold_line_style(background_color)
Expand Down Expand Up @@ -230,28 +237,25 @@ impl Chart<Message> for BalanceChart {
)))
.expect("Failed to draw hover point");

// TODO these colors should be black when the theme is light. Solution A: we can either expand the
// color_palette struct to include a text color. Solution B: we can extend the ice-plotter lib to send the style down draw so we can
// tap into the system default text color like we have everywhere else. Solution C: meh, just hardcode it for now, white suffices on most
// backgrounds.
// draw balance above the point
chart
.draw_series(std::iter::once(Text::new(
format!("{}", amount),
(time, max_value),
("sans-serif", CHART_CAPTION_HEAD)
.into_font()
.color(&plotters::style::colors::WHITE.mix(1.0)),
.color(&text_color.mix(1.0))
)))
.expect("Failed to draw text");

// date
// date below balance with a slight faded color
chart
.draw_series(std::iter::once(Text::new(
format!("{}", time.format("%b %d, %Y")),
(time, max_value * 0.84),
("sans-serif", CHART_CAPTION_SUB)
.into_font()
.color(&plotters::style::colors::WHITE.mix(0.5)),
.color(&text_color.mix(0.7))
)))
.expect("Failed to draw text");
}
Expand Down
85 changes: 61 additions & 24 deletions src/gui/element/wallet/operation/tx_list_display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use grin_gui_core::{
use grin_gui_widgets::widget::header;
use iced_aw::Card;
use iced_native::Widget;
use std::{path::PathBuf, str::FromStr};
use std::{borrow::Borrow, path::PathBuf, str::FromStr};

use super::tx_list::{HeaderState, TxList, TxLogEntryWrap};

Expand Down Expand Up @@ -40,11 +40,15 @@ use {
};

pub struct StateContainer {
// maintains a list of all confirmed transactions sorted by date
confirmed_txns: Vec<TxLogEntry>,
wallet_txs: TxList,
tx_header_state: HeaderState,
mode: Mode,

pub expanded_type: ExpandType,

// balance history for wallet as (date, grin_balance)
pub balance_data: Vec<(chrono::DateTime<chrono::Utc>, f64)>,
}

Expand All @@ -56,6 +60,7 @@ impl Default for StateContainer {
expanded_type: ExpandType::None,
mode: Mode::NotInit,
balance_data: vec![],
confirmed_txns: vec![],
}
}
}
Expand Down Expand Up @@ -137,37 +142,69 @@ pub fn handle_message<'a>(
.collect();
state.wallet_txs = TxList { txs: tx_wrap_list };

let mut datetime_sums = vec![];
for (idx, tx) in txs.iter().enumerate() {
if tx.confirmed {
// trunc transaction date to day
//let datetime = tx.confirmation_ts.unwrap().duration_trunc(chrono::Duration::days(1)).unwrap();
let datetime = chrono::DateTime::from_str("2019-01-20T00:00:00Z").unwrap();
let credits = tx.amount_credited;
let debits = tx.amount_debited;
let confirmed_txns: Vec<&TxLogEntry> = txs.iter().filter(|tx| tx.confirmed).collect();

if !confirmed_txns.is_empty() {
// added new confirmed transactions to state confirmed set?
let mut added = false;

datetime_sums.push((datetime, credits - debits));
for tx in confirmed_txns.iter() {
// if tx is not in state confirmed transactions, add it
if state
.confirmed_txns
.iter()
.find(|t| t.id == tx.id)
.is_none()
{
// push to state confirmed transactions
state.confirmed_txns.push(tx.clone().to_owned());
added = true;
debug!("Confirmed Tx: {:?}", tx);
}
}
}

// fill in sum data for days without transactions
if !datetime_sums.is_empty() {
let mut sum = 0;
let mut dt = datetime_sums.first().unwrap().0;
let today = chrono::Utc::now().duration_trunc(chrono::Duration::days(1)).unwrap();
if added {
// sort state transactions by date
state.confirmed_txns.sort_by(|a, b| {
a.confirmation_ts.unwrap().cmp(&b.confirmation_ts.unwrap())
});

let mut datetime_sums = vec![];
for tx in state.confirmed_txns.iter() {
// trunc transaction date to day
//let datetime = tx.confirmation_ts.unwrap().duration_trunc(chrono::Duration::days(1)).unwrap();
// this should be the date time above but for dev purposes lets backdate it
let datetime = chrono::DateTime::from_str("2019-01-20T00:00:00Z").unwrap();
let credits = tx.amount_credited;
let debits = tx.amount_debited;

datetime_sums.push((datetime, credits - debits));
}

while dt <= today {
let txns = datetime_sums
.iter()
.filter(|(date, _)| *date == dt);
let mut sum = 0;
let mut dt = datetime_sums.first().unwrap().0;
let today = chrono::Utc::now()
.duration_trunc(chrono::Duration::days(1))
.unwrap();

sum = sum + txns.map(|x| x.1).collect::<Vec<_>>().iter().sum::<u64>();
// fill in sum data for days without transactions
let mut balance_history = vec![];
while dt <= today {
// get all transactions for this date
let txns = datetime_sums.iter().filter(|(date, _)| *date == dt);

let dec_sum = (sum as f64 / grin_gui_core::GRIN_BASE as f64) as f64;
// sum up balance amount
sum = sum + txns.map(|x| x.1).collect::<Vec<_>>().iter().sum::<u64>();

state.balance_data.push((dt.to_owned(), dec_sum));
// convert to grin units
let grin_sum = (sum as f64 / grin_gui_core::GRIN_BASE as f64) as f64;
balance_history.push((dt.to_owned(), grin_sum));

dt = dt + chrono::Duration::days(1);
}

dt = dt + chrono::Duration::days(1);
// finally we update state with the newly constructed balance history
state.balance_data = balance_history;
}
}
}
Expand Down