Merge #285: gui: order coins list in coins panel

d81c22767c489d5a11db78cc34f59eb008f431f9 gui: order coins list in coins panel (edouard)

Pull request description:

  close #193

ACKs for top commit:
  edouardparis:
    Self-ACK d81c22767c489d5a11db78cc34f59eb008f431f9

Tree-SHA512: 9ae179b38aaea7b5e74f071b9f7788996ae76de858f81be61169efcb75a4507d1245d210715b829cd2fe4151cd519a68bb2d75d422df9a98ff2b4a9559baf013
This commit is contained in:
edouard 2023-01-13 16:40:21 +01:00
commit f3b9a26b95
No known key found for this signature in database
GPG Key ID: E65F7A089C20DC8F

View File

@ -1,3 +1,4 @@
use std::cmp::Ordering;
use std::sync::Arc;
use iced::{Command, Element};
@ -17,21 +18,41 @@ pub struct CoinsPanel {
impl CoinsPanel {
pub fn new(coins: &[Coin], timelock: u32) -> Self {
Self {
coins: coins
.iter()
.filter_map(|coin| {
if coin.spend_info.is_none() {
Some(*coin)
} else {
None
}
})
.collect(),
let mut panel = Self {
coins: Vec::new(),
selected: Vec::new(),
warning: None,
timelock,
}
};
panel.update_coins(coins);
panel
}
fn update_coins(&mut self, coins: &[Coin]) {
self.coins = coins
.iter()
.filter_map(|coin| {
if coin.spend_info.is_none() {
Some(*coin)
} else {
None
}
})
.collect();
self.coins
.sort_by(|a, b| match (a.block_height, b.block_height) {
(Some(a_height), Some(b_height)) => {
if a_height == b_height {
a.outpoint.vout.cmp(&b.outpoint.vout)
} else {
a_height.cmp(&b_height)
}
}
(None, Some(_)) => Ordering::Greater,
(Some(_), None) => Ordering::Less,
(None, None) => a.outpoint.vout.cmp(&b.outpoint.vout),
})
}
}
@ -57,16 +78,7 @@ impl State for CoinsPanel {
Ok(coins) => {
self.selected = Vec::new();
self.warning = None;
self.coins = coins
.iter()
.filter_map(|coin| {
if coin.spend_info.is_none() {
Some(*coin)
} else {
None
}
})
.collect();
self.update_coins(&coins);
}
},
Message::View(view::Message::Select(i)) => {
@ -100,3 +112,61 @@ impl From<CoinsPanel> for Box<dyn State> {
Box::new(s)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::daemon::model::Coin;
use liana::miniscript::bitcoin;
use std::str::FromStr;
#[test]
fn test_coins_panel_update_coins() {
let mut panel = CoinsPanel::new(&[], 0);
let txid = bitcoin::Txid::from_str(
"f7bd1b2a995b689d326e51eb742eb1088c4a8f110d9cb56128fd553acc9f88e5",
)
.unwrap();
panel.update_coins(&[
Coin {
outpoint: bitcoin::OutPoint { txid, vout: 2 },
amount: bitcoin::Amount::from_sat(1),
block_height: Some(3),
spend_info: None,
},
Coin {
outpoint: bitcoin::OutPoint { txid, vout: 3 },
amount: bitcoin::Amount::from_sat(1),
block_height: None,
spend_info: None,
},
Coin {
outpoint: bitcoin::OutPoint { txid, vout: 0 },
amount: bitcoin::Amount::from_sat(1),
block_height: Some(2),
spend_info: None,
},
Coin {
outpoint: bitcoin::OutPoint { txid, vout: 1 },
amount: bitcoin::Amount::from_sat(1),
block_height: Some(3),
spend_info: None,
},
]);
assert_eq!(
panel
.coins
.iter()
.map(|c| c.outpoint)
.collect::<Vec<bitcoin::OutPoint>>(),
vec![
bitcoin::OutPoint { txid, vout: 0 },
bitcoin::OutPoint { txid, vout: 1 },
bitcoin::OutPoint { txid, vout: 2 },
bitcoin::OutPoint { txid, vout: 3 },
]
)
}
}