diff options
Diffstat (limited to 'schist_desktop_gui/src/gui')
9 files changed, 551 insertions, 104 deletions
diff --git a/schist_desktop_gui/src/gui/components.rs b/schist_desktop_gui/src/gui/components.rs index bb5590f..606c418 100644 --- a/schist_desktop_gui/src/gui/components.rs +++ b/schist_desktop_gui/src/gui/components.rs @@ -1,3 +1,4 @@ +mod account_navigation_entry; pub mod balances_view; pub mod bucket_navigation_entry; pub mod buckets_view; @@ -7,6 +8,7 @@ pub mod panel; pub mod text; pub mod transactions_view; +pub use account_navigation_entry::AccountNavigationEntry; pub use balances_view::BalancesView; pub use bucket_navigation_entry::BucketNavigationEntry; pub use buckets_view::BucketsView; diff --git a/schist_desktop_gui/src/gui/components/account_navigation_entry.rs b/schist_desktop_gui/src/gui/components/account_navigation_entry.rs new file mode 100644 index 0000000..6a582a7 --- /dev/null +++ b/schist_desktop_gui/src/gui/components/account_navigation_entry.rs @@ -0,0 +1,34 @@ +use iced::Element; +use schist_models::Account; + +use crate::{ + gui::components::{navigation, Text}, + impl_focusable, +}; + +#[derive(Clone, Debug, PartialEq)] +pub struct AccountNavigationEntry { + pub account: Account, + is_focused: bool, +} + +impl AccountNavigationEntry { + pub fn new(account: Account) -> Self { + Self { + account, + is_focused: false, + } + } +} + +impl<'a> From<&'a AccountNavigationEntry> + for Element<'a, navigation::Message<AccountNavigationEntry>> +{ + fn from(account_navigation_entry: &'a AccountNavigationEntry) -> Self { + Text::default(&account_navigation_entry.account.name) + .highlight_maybe(account_navigation_entry.is_focused) + .into() + } +} + +impl_focusable!(AccountNavigationEntry); diff --git a/schist_desktop_gui/src/gui/components/balances_view/view_balances_view.rs b/schist_desktop_gui/src/gui/components/balances_view/view_balances_view.rs index 22f22b6..013a6fb 100644 --- a/schist_desktop_gui/src/gui/components/balances_view/view_balances_view.rs +++ b/schist_desktop_gui/src/gui/components/balances_view/view_balances_view.rs @@ -24,7 +24,7 @@ impl<'a> Viewable<'a, Message> for BalancesView { ] .align_y(alignment::Vertical::Center) .height(Length::Fill) - .spacing(SPACING_LG) + .spacing(u32::from(SPACING_LG)) .into() } } diff --git a/schist_desktop_gui/src/gui/components/buckets_view.rs b/schist_desktop_gui/src/gui/components/buckets_view.rs index 7f5b218..8f12019 100644 --- a/schist_desktop_gui/src/gui/components/buckets_view.rs +++ b/schist_desktop_gui/src/gui/components/buckets_view.rs @@ -115,7 +115,7 @@ impl<'a> Viewable<'a, Message> for BucketsView { ] .align_y(alignment::Vertical::Center) .height(Length::Fill) - .spacing(SPACING_LG) + .spacing(u32::from(SPACING_LG)) .into() } } diff --git a/schist_desktop_gui/src/gui/components/panel.rs b/schist_desktop_gui/src/gui/components/panel.rs index 364659b..85bfb97 100644 --- a/schist_desktop_gui/src/gui/components/panel.rs +++ b/schist_desktop_gui/src/gui/components/panel.rs @@ -39,7 +39,7 @@ where cols.push( Text::default(err) .highlight_maybe(value.is_focused) - .small() + .v_small() .danger() .into(), ); @@ -48,7 +48,7 @@ where cols.push( Text::default(small) .highlight_maybe(value.is_focused) - .small() + .v_small() .weak() .into(), ); diff --git a/schist_desktop_gui/src/gui/components/text.rs b/schist_desktop_gui/src/gui/components/text.rs index d171043..068e89a 100644 --- a/schist_desktop_gui/src/gui/components/text.rs +++ b/schist_desktop_gui/src/gui/components/text.rs @@ -1,17 +1,29 @@ use std::borrow::Borrow; +use iced::{font, widget::container, Font}; + use crate::{impl_focusable, style::*}; #[derive(Clone, Debug, PartialEq)] pub struct Text { pub content: String, + align: Alignment, colour: Option<Colour>, + font_style: font::Style, + overflow_strategy: OverflowStrategy, size: Option<Size>, strength: Option<Strength>, + width: iced::Length, is_focused: bool, } #[derive(Clone, Debug, PartialEq)] +enum Alignment { + Left, + Right, +} + +#[derive(Clone, Debug, PartialEq)] enum Colour { Danger, Primary, @@ -19,6 +31,12 @@ enum Colour { } #[derive(Clone, Debug, PartialEq)] +enum OverflowStrategy { + Grow, + Clip, +} + +#[derive(Clone, Debug, PartialEq)] enum Strength { Base, Weak, @@ -26,6 +44,7 @@ enum Strength { #[derive(Clone, Debug, PartialEq)] enum Size { + VSmall, Small, Base, } @@ -33,28 +52,55 @@ enum Size { impl Text { pub fn default(content: &str) -> Self { Self { + align: Alignment::Left, content: String::from(content), colour: Some(Colour::Primary), + font_style: font::Style::Normal, + overflow_strategy: OverflowStrategy::Grow, size: Some(Size::Base), strength: Some(Strength::Base), is_focused: false, + width: iced::Length::Shrink, } } pub fn new(content: &str) -> Self { Self { + align: Alignment::Left, content: String::from(content), colour: None, + font_style: font::Style::Normal, + overflow_strategy: OverflowStrategy::Grow, size: None, strength: None, + width: iced::Length::Shrink, is_focused: false, } } - pub fn as_element<'a, Message>(self) -> iced::Element<'a, Message> { + pub fn currency(amount: i32) -> Self { + let formatted_string = if amount < 0 { + format!("({} · {})", -amount / 100, -amount % 100) + } else { + format!(" {} · {} ", amount / 100, amount % 100) + }; + Self::default(&formatted_string) + } + + pub fn as_element<'a, Message>(self) -> iced::Element<'a, Message> + where + Message: 'a, + { <Self as Into<iced::Element<'a, Message>>>::into(self) } + pub fn v_small(&self) -> Self { + Self { + size: Some(Size::VSmall), + ..self.clone() + } + } + pub fn small(&self) -> Self { Self { size: Some(Size::Small), @@ -86,15 +132,56 @@ impl Text { self.clone() } } + + pub fn align_right(&self) -> Self { + Self { + align: Alignment::Right, + ..self.clone() + } + } + + pub fn width(&self, width: iced::Length) -> Self { + Self { + width, + ..self.clone() + } + } + + pub fn clip(&self) -> Self { + Self { + overflow_strategy: OverflowStrategy::Clip, + ..self.clone() + } + } + + pub fn italic(&self) -> Self { + Self { + font_style: font::Style::Italic, + ..self.clone() + } + } + + pub fn style(&self, font_style: font::Style) -> Self { + Self { + font_style, + ..self.clone() + } + } } -impl<'a, Message> From<Text> for iced::Element<'a, Message> { +impl<'a, Message> From<Text> for iced::Element<'a, Message> +where + Message: 'a, +{ fn from(text: Text) -> Self { text_as_element(text) } } -impl<'a, Message> From<&'a Text> for iced::Element<'a, Message> { +impl<'a, Message> From<&'a Text> for iced::Element<'a, Message> +where + Message: 'a, +{ fn from(text: &'a Text) -> Self { text_as_element(text) } @@ -103,17 +190,31 @@ impl<'a, Message> From<&'a Text> for iced::Element<'a, Message> { fn text_as_element<'a, T, Message>(text: T) -> iced::Element<'a, Message> where T: Borrow<Text> + 'a, + Message: 'a, { - iced::widget::text(text.borrow().content.clone()) + let overflow_strategy = &text.borrow().overflow_strategy.clone(); + + let text_elem: iced::widget::Text = iced::widget::text(text.borrow().content.clone()) + .font(Font { + style: text.borrow().font_style, + ..Default::default() + }) .size(match text.borrow().size { - Some(Size::Small) => TEXT_SIZE_SM, - Some(Size::Base) | None => TEXT_SIZE_BASE, + Some(Size::VSmall) => u32::from(TEXT_SIZE_V_SM), + Some(Size::Small) => u32::from(TEXT_SIZE_SM), + Some(Size::Base) | None => u32::from(TEXT_SIZE_BASE), + }) + .align_x(match &text.borrow().align { + Alignment::Left => iced::alignment::Horizontal::Left, + Alignment::Right => iced::alignment::Horizontal::Right, }) + .wrapping(match overflow_strategy { + OverflowStrategy::Grow => iced::widget::text::Wrapping::default(), + OverflowStrategy::Clip => iced::widget::text::Wrapping::None, + }) + .width(text.borrow().width) .style(move |theme: &iced::Theme| iced::widget::text::Style { - color: match ( - &text.borrow().borrow().colour, - &text.borrow().borrow().strength, - ) { + color: match (&text.borrow().colour, &text.borrow().strength) { (Some(Colour::Danger), Some(Strength::Base) | None) => { Some(theme.extended_palette().danger.base.text) } @@ -134,8 +235,15 @@ where } (None, _) => None, }, - }) - .into() + }); + + match overflow_strategy { + OverflowStrategy::Grow => text_elem.into(), + OverflowStrategy::Clip => container::<'a, Message, _, _>(text_elem) + .height(iced::Length::Shrink) + .clip(true) + .into(), + } } impl_focusable!(Text); diff --git a/schist_desktop_gui/src/gui/components/transactions_view.rs b/schist_desktop_gui/src/gui/components/transactions_view.rs index 1cb569c..a52c419 100644 --- a/schist_desktop_gui/src/gui/components/transactions_view.rs +++ b/schist_desktop_gui/src/gui/components/transactions_view.rs @@ -1,122 +1,295 @@ -use iced::{ - alignment, - widget::{column, row, Container}, - Element, Length, -}; -use schist_models::Account; +mod view_transactions_view; + +use std::collections::{HashMap, VecDeque}; + +use iced::font; +use itertools::Itertools; +use schist_models::{Account, AccountTransfer, Bucket, DateUtc, Transaction}; use crate::{ - gui::components::{navigation, Navigation, Text}, - style::SPACING_LG, - traits::{Component, Viewable}, + gui::components::{navigation, AccountNavigationEntry, Navigation}, + traits::Component, }; #[derive(Clone, Debug)] pub struct TransactionsView { accounts: Vec<Account>, - greeting: String, - navigation: Navigation<Text>, + account_transfers: Vec<AccountTransfer>, + buckets: Vec<Bucket>, + navigation: Navigation<AccountNavigationEntry>, + transactions: Vec<Transaction>, + transaction_rows_by_account_id: HashMap<i32, Vec<TransactionRow>>, } #[derive(Clone, Debug)] pub enum Message { - NavigationMessage(navigation::Message<Text>), - SelectNextTransaction, - SelectPrevTransaction, + NavigationMessage(navigation::Message<AccountNavigationEntry>), + SelectNextAccount, + SelectPrevAccount, SetAccounts(Vec<Account>), + SetAccountTransfers(Vec<AccountTransfer>), + SetBuckets(Vec<Bucket>), + SetTransactions(Vec<Transaction>), } pub enum Action { None, } -impl TransactionsView { - pub fn new(accounts: Vec<Account>, greeting: &str) -> Self { - let account_names = view_account_names(accounts.clone()); - let navigation = Navigation::new(account_names.clone().first().cloned(), account_names); - Self { - accounts: accounts, - greeting: greeting.to_owned(), - navigation: navigation, +#[derive(Debug, PartialEq, Eq)] +struct TransactionRowWithoutAggregations { + amount: i32, + bucket: String, + bucket_font_style: font::Style, + date: DateUtc, + payee: String, + payee_font_style: font::Style, +} + +impl TransactionRowWithoutAggregations { + fn from_transaction( + account_id: i32, + transaction: &Transaction, + buckets: &[Bucket], + ) -> Option<Self> { + if transaction.account_id == account_id { + let (bucket, bucket_font_style) = match transaction.bucket_id { + Some(bucket_id) => match buckets.iter().find(|b| b.id == bucket_id) { + Some(bucket) => (bucket.name.clone(), font::Style::Normal), + None => (format!("Bucket <{}>", bucket_id), font::Style::Italic), + }, + None => (String::from("None"), font::Style::Italic), + }; + Some(Self { + amount: transaction.amount, + bucket, + bucket_font_style, + date: transaction.date, + payee: transaction.counterparty.clone(), + payee_font_style: font::Style::Normal, + }) + } else { + None + } + } + + fn from_account_transfer( + account_id: i32, + account_transfer: &AccountTransfer, + accounts: &[Account], + ) -> Option<Self> { + if account_transfer.from_account_id == account_id { + let (payee, payee_font_style) = if let Some(account) = accounts + .iter() + .find(|a| a.id == account_transfer.to_account_id) + { + (account.name.clone(), font::Style::Normal) + } else { + (format!("<{}>", account_id), font::Style::Italic) + }; + Some(Self { + amount: -account_transfer.amount, + bucket: String::from("Account transfer"), + bucket_font_style: font::Style::Italic, + date: account_transfer.date, + payee, + payee_font_style, + }) + } else if account_transfer.to_account_id == account_id { + let (payee, payee_font_style) = if let Some(account) = accounts + .iter() + .find(|a| a.id == account_transfer.from_account_id) + { + (account.name.clone(), font::Style::Normal) + } else { + (format!("Account <{}>", account_id), font::Style::Italic) + }; + Some(Self { + amount: account_transfer.amount, + bucket: String::from("Account transfer"), + bucket_font_style: font::Style::Italic, + date: account_transfer.date, + payee, + payee_font_style, + }) + } else { + None } } + + fn with_aggregations(self, balance: i32) -> TransactionRow { + TransactionRow { + amount: self.amount, + balance, + bucket: self.bucket, + bucket_font_style: self.bucket_font_style, + date: self.date, + payee: self.payee, + payee_font_style: self.payee_font_style, + } + } + + fn compare_date_desc(&self, other: &Self) -> std::cmp::Ordering { + other.date.cmp(&self.date) + } +} + +impl std::cmp::PartialOrd for TransactionRowWithoutAggregations { + fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> { + Some(self.compare_date_desc(other)) + } } -impl<'a> Viewable<'a, Message> for TransactionsView { - fn view(&'a self) -> Element<'a, Message> { - let navigation = self.navigation.view().map(Message::NavigationMessage); - let main_content = column![Text::default(&self.greeting).as_element()]; - row![ - Container::new(navigation).width(Length::FillPortion(1)), - Container::new(main_content).width(Length::FillPortion(3)), - ] - .align_y(alignment::Vertical::Center) - .height(Length::Fill) - .spacing(SPACING_LG) - .into() +impl std::cmp::Ord for TransactionRowWithoutAggregations { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + self.compare_date_desc(other) + } +} + +#[derive(Clone, Debug, Hash)] +struct TransactionRow { + amount: i32, + balance: i32, + bucket: String, + bucket_font_style: font::Style, + date: DateUtc, + payee: String, + payee_font_style: font::Style, +} + +impl TransactionsView { + pub fn new( + accounts: &[Account], + account_transfers: &[AccountTransfer], + buckets: &[Bucket], + transactions: &[Transaction], + ) -> Self { + let account_navigation_entries: Vec<AccountNavigationEntry> = accounts + .iter() + .cloned() + .map(AccountNavigationEntry::new) + .collect(); + let navigation = Navigation::new( + account_navigation_entries.first().cloned(), + account_navigation_entries, + ); + let transaction_rows_by_account_id = + calculate_rows(accounts, account_transfers, buckets, transactions); + Self { + accounts: accounts.to_vec(), + account_transfers: account_transfers.to_vec(), + buckets: buckets.to_vec(), + navigation: navigation, + transactions: transactions.to_vec(), + transaction_rows_by_account_id, + } } } impl<'a> Component<'a, Message, Action> for TransactionsView { fn update(&mut self, message: Message) -> Action { match message { - Message::NavigationMessage(message) => { - match self.navigation.update(message) { - navigation::Action::ActivateOption(group_name) - | navigation::Action::SelectOption(group_name) => { - self.greeting = make_greeting(group_name); - Action::None - } - navigation::Action::None => Action::None, - }; - Action::None - } + Message::NavigationMessage(message) => self.update_navigation(message), + Message::SetAccounts(accounts) => { self.accounts = accounts.clone(); - match self - .navigation - .update(navigation::Message::SetOptions(view_account_names( - accounts, - ))) { - navigation::Action::ActivateOption(option) - | navigation::Action::SelectOption(option) => { - self.greeting = make_greeting(option); - Action::None - } - navigation::Action::None => Action::None, - } + self.transaction_rows_by_account_id = calculate_rows( + &self.accounts, + &self.account_transfers, + &self.buckets, + &self.transactions, + ); + let account_navigation_entries: Vec<AccountNavigationEntry> = accounts + .into_iter() + .map(AccountNavigationEntry::new) + .collect(); + self.update_navigation(navigation::Message::SetOptions(account_navigation_entries)) } - Message::SelectNextTransaction => { - match self.navigation.update(navigation::Message::SelectNext) { - navigation::Action::ActivateOption(option) - | navigation::Action::SelectOption(option) => { - self.greeting = make_greeting(option); - Action::None - } - navigation::Action::None => Action::None, - } + + Message::SetAccountTransfers(account_transfers) => { + self.account_transfers = account_transfers; + self.transaction_rows_by_account_id = calculate_rows( + &self.accounts, + &self.account_transfers, + &self.buckets, + &self.transactions, + ); + Action::None + } + + Message::SetBuckets(buckets) => { + self.buckets = buckets; + self.transaction_rows_by_account_id = calculate_rows( + &self.accounts, + &self.account_transfers, + &self.buckets, + &self.transactions, + ); + Action::None } - Message::SelectPrevTransaction => { - match self.navigation.update(navigation::Message::SelectPrev) { - navigation::Action::ActivateOption(option) - | navigation::Action::SelectOption(option) => { - self.greeting = make_greeting(option); - Action::None - } - navigation::Action::None => Action::None, - } + + Message::SetTransactions(transactions) => { + self.transactions = transactions; + self.transaction_rows_by_account_id = calculate_rows( + &self.accounts, + &self.account_transfers, + &self.buckets, + &self.transactions, + ); + Action::None } + + Message::SelectNextAccount => self.update_navigation(navigation::Message::SelectNext), + + Message::SelectPrevAccount => self.update_navigation(navigation::Message::SelectPrev), } } } -fn make_greeting(account_name: Text) -> String { - format!("Hello, {} account!", account_name.content) +impl TransactionsView { + fn update_navigation( + &mut self, + message: navigation::Message<AccountNavigationEntry>, + ) -> Action { + match self.navigation.update(message) { + navigation::Action::ActivateOption(_) | navigation::Action::SelectOption(_) => { + Action::None + } + navigation::Action::None => Action::None, + } + } } -fn view_account_names(accounts: Vec<Account>) -> Vec<Text> { - accounts - .iter() - .map(|acc| Text::new(acc.name.as_str())) - .collect() +fn calculate_rows( + accounts: &[Account], + account_transfers: &[AccountTransfer], + buckets: &[Bucket], + transactions: &[Transaction], +) -> HashMap<i32, Vec<TransactionRow>> { + HashMap::from_iter(accounts.iter().map(|account| { + let transaction_rows_without_aggs = transactions + .iter() + .filter_map(|t| { + TransactionRowWithoutAggregations::from_transaction(account.id, t, buckets) + }) + .chain(account_transfers.iter().filter_map(|at| { + TransactionRowWithoutAggregations::from_account_transfer(account.id, at, accounts) + })) + .sorted(); + + let mut running_balance: i32 = 0; + let mut transaction_rows = VecDeque::with_capacity(transaction_rows_without_aggs.len()); + for row in transaction_rows_without_aggs.rev() { + if running_balance.checked_add(row.amount).is_none() { + panic!( + "can't add {} + {}. row: {:?}", + running_balance, row.amount, row + ); + } + running_balance += row.amount; + transaction_rows.push_front(row.with_aggregations(running_balance)); + } + + (account.id, transaction_rows.into()) + })) } diff --git a/schist_desktop_gui/src/gui/components/transactions_view/view_transactions_view.rs b/schist_desktop_gui/src/gui/components/transactions_view/view_transactions_view.rs new file mode 100644 index 0000000..268984b --- /dev/null +++ b/schist_desktop_gui/src/gui/components/transactions_view/view_transactions_view.rs @@ -0,0 +1,112 @@ +use iced::{ + alignment, + widget::{ + row, + scrollable::{self, Scrollbar}, + table, + table::column, + Container, Scrollable, + }, + Element, Length, +}; + +use crate::{gui::components::Text, style::SPACING_LG, traits::Viewable}; + +use super::{Message, TransactionRow, TransactionsView}; + +impl<'a> Viewable<'a, Message> for TransactionsView { + fn view(&'a self) -> Element<'a, Message> { + let navigation = self.navigation.view().map(Message::NavigationMessage); + + let columns = [ + column( + Text::default("Date").width(iced::Length::Fixed(128.0)), + view_date_cell, + ), + column( + Text::default("Bucket").width(iced::Length::Fixed(128.0)), + view_bucket_cell, + ), + column( + Text::default("Payee").width(iced::Length::Fixed(256.0)), + view_payee_cell, + ), + column( + Text::default("Quantity") + .width(iced::Length::Fixed(96.0)) + .align_right(), + view_quantity_cell, + ), + column( + Text::default("Balance") + .width(iced::Length::Fixed(96.0)) + .align_right(), + view_balance_cell, + ), + ]; + + let rows = self + .navigation + .active_option + .clone() + .map_or_else(Vec::default, |option| { + self.transaction_rows_by_account_id + .get(&option.account.id) + .cloned() + .unwrap_or_else(Vec::default) + }); + + let table = Scrollable::new(table(columns, rows)).direction(scrollable::Direction::Both { + horizontal: Scrollbar::default(), + vertical: Scrollbar::default(), + }); + + row![ + Container::new(navigation).width(Length::FillPortion(1)), + Container::new(table).width(Length::FillPortion(3)), + ] + .align_y(alignment::Vertical::Center) + .height(Length::Fill) + .spacing(u32::from(SPACING_LG)) + .into() + } +} + +fn view_date_cell(row: TransactionRow) -> Text { + Text::default(row.date.format("%e %b %Y").as_str()) + .width(iced::Length::Fixed(128.0)) + .small() + .clip() +} + +fn view_bucket_cell(row: TransactionRow) -> Text { + Text::default(&row.bucket) + .style(row.bucket_font_style) + .width(iced::Length::Fixed(128.0)) + .small() + .clip() +} + +fn view_payee_cell(row: TransactionRow) -> Text { + Text::default(&row.payee) + .style(row.payee_font_style) + .width(iced::Length::Fixed(256.0)) + .small() + .clip() +} + +fn view_quantity_cell(row: TransactionRow) -> Text { + Text::currency(row.amount) + .width(iced::Length::Fixed(96.0)) + .small() + .clip() + .align_right() +} + +fn view_balance_cell(row: TransactionRow) -> Text { + Text::currency(row.balance) + .width(iced::Length::Fixed(96.0)) + .small() + .clip() + .align_right() +} diff --git a/schist_desktop_gui/src/gui/screens/main_screen/main_screen.rs b/schist_desktop_gui/src/gui/screens/main_screen/main_screen.rs index 5ed4b30..6580758 100644 --- a/schist_desktop_gui/src/gui/screens/main_screen/main_screen.rs +++ b/schist_desktop_gui/src/gui/screens/main_screen/main_screen.rs @@ -4,7 +4,7 @@ use iced::{ widget::{row, Container}, Element, Length, }; -use schist_models::{Account, Bucket}; +use schist_models::{Account, AccountTransfer, Bucket, Transaction}; use crate::{ gui::components::{ @@ -35,7 +35,9 @@ pub enum Message { TransactionsViewMessage(transactions_view::Message), SelectView(View), SetAccounts(Vec<Account>), + SetAccountTransfers(Vec<AccountTransfer>), SetBuckets(Vec<Bucket>), + SetTransactions(Vec<Transaction>), ViewNavigationMessage(navigation::Message<View>), } @@ -64,7 +66,7 @@ impl<'a> Viewable<'a, Message> for MainScreen { ] .align_y(alignment::Vertical::Center) .height(Length::Fill) - .spacing(SPACING_LG) + .spacing(u32::from(SPACING_LG)) .into() } } @@ -108,7 +110,9 @@ impl<'a> Component<'a, Message, Action> for MainScreen { self.balances_view .update(balances_view::Message::SetBuckets(buckets.clone())); self.buckets_view - .update(buckets_view::Message::SetBuckets(buckets)); + .update(buckets_view::Message::SetBuckets(buckets.clone())); + self.transactions_view + .update(transactions_view::Message::SetBuckets(buckets)); Action::None } @@ -118,6 +122,20 @@ impl<'a> Component<'a, Message, Action> for MainScreen { Action::None } + Message::SetAccountTransfers(account_transfers) => { + self.transactions_view + .update(transactions_view::Message::SetAccountTransfers( + account_transfers, + )); + Action::None + } + + Message::SetTransactions(transactions) => { + self.transactions_view + .update(transactions_view::Message::SetTransactions(transactions)); + Action::None + } + Message::NextItem => match self.active_view { View::Balances => { self.balances_view @@ -130,7 +148,7 @@ impl<'a> Component<'a, Message, Action> for MainScreen { } View::Transactions => { self.transactions_view - .update(transactions_view::Message::SelectNextTransaction); + .update(transactions_view::Message::SelectNextAccount); Action::None } }, @@ -147,7 +165,7 @@ impl<'a> Component<'a, Message, Action> for MainScreen { } View::Transactions => { self.transactions_view - .update(transactions_view::Message::SelectPrevTransaction); + .update(transactions_view::Message::SelectPrevAccount); Action::None } }, @@ -197,7 +215,7 @@ impl MainScreen { balances_view: BalancesView::new(Vec::new()), buckets: Vec::new(), buckets_view: BucketsView::new(Vec::new(), "Hello, buckets!"), - transactions_view: TransactionsView::new(Vec::new(), "Hello, transactions!"), + transactions_view: TransactionsView::new(&[], &[], &[], &[]), active_view: View::Balances, view_navigation: Navigation::new(Some(View::Balances), View::views()), } |
