koibumi 0.0.10

An experimental Bitmessage client
use std::collections::HashMap;

use iced::{
    widget::{scrollable, Column, Row, Text},
    Color, Element, Length,
};

use koibumi_core::message::UserAgent;
use koibumi_node::{Rating, SocketAddrNode};

use crate::{config::Config as GuiConfig, gui::Message};

#[derive(Clone, Debug, Default)]
pub(crate) struct Tab {
    pub(crate) incoming_initiated: usize,
    pub(crate) incoming_connected: usize,
    pub(crate) incoming_established: usize,
    pub(crate) outgoing_initiated: usize,
    pub(crate) outgoing_connected: usize,
    pub(crate) outgoing_established: usize,

    pub(crate) addr_count: usize,

    pub(crate) peers: Vec<SocketAddrNode>,
    pub(crate) peer_infos: HashMap<SocketAddrNode, (UserAgent, Rating)>,

    pub(crate) missing_objects: usize,
    pub(crate) loaded_objects: usize,
    pub(crate) uploaded_objects: usize,
}

impl Tab {
    pub(crate) fn view(&self, config: &GuiConfig) -> Element<Message> {
        let text_size = config.text_size();

        let color = Color {
            r: 0.0,
            g: 0.0,
            b: 1.0,
            a: 1.0,
        };

        let objects = Row::new()
            .spacing(text_size / 2)
            .push(Text::new("Objects:").size(text_size))
            .push(
                Text::new(self.missing_objects.to_string())
                    .size(text_size)
                    .style(color),
            )
            .push(Text::new("missing,").size(text_size))
            .push(
                Text::new(self.loaded_objects.to_string())
                    .size(text_size)
                    .style(color),
            )
            .push(Text::new("loaded,").size(text_size))
            .push(
                Text::new(self.uploaded_objects.to_string())
                    .size(text_size)
                    .style(color),
            )
            .push(Text::new("uploaded").size(text_size));

        let addr_count = Row::new()
            .spacing(text_size / 2)
            .push(
                Text::new(self.addr_count.to_string())
                    .size(text_size)
                    .style(color),
            )
            .push(Text::new("addresses").size(text_size));

        let incoming_initiated_text = Text::new(self.incoming_initiated.to_string())
            .size(text_size)
            .style(color);
        let incoming_connected_text = Text::new(self.incoming_connected.to_string())
            .size(text_size)
            .style(color);
        let incoming_established_text = Text::new(self.incoming_established.to_string())
            .size(text_size)
            .style(color);
        let incoming = Row::new()
            .spacing(text_size / 2)
            .push(Text::new("Incoming:").size(text_size))
            .push(incoming_initiated_text)
            .push(Text::new("initiated,").size(text_size))
            .push(incoming_connected_text)
            .push(Text::new("connected,").size(text_size))
            .push(incoming_established_text)
            .push(Text::new("established").size(text_size));

        let outgoing_initiated_text = Text::new(self.outgoing_initiated.to_string())
            .size(text_size)
            .style(color);
        let outgoing_connected_text = Text::new(self.outgoing_connected.to_string())
            .size(text_size)
            .style(color);
        let outgoing_established_text = Text::new(self.outgoing_established.to_string())
            .size(text_size)
            .style(color);
        let outgoing = Row::new()
            .spacing(text_size / 2)
            .push(Text::new("Outgoing:").size(text_size))
            .push(outgoing_initiated_text)
            .push(Text::new("initiated,").size(text_size))
            .push(outgoing_connected_text)
            .push(Text::new("connected,").size(text_size))
            .push(outgoing_established_text)
            .push(Text::new("established").size(text_size));

        let mut list = Column::new();
        for addr in &self.peers {
            if let Some((user_agent, rating)) = self.peer_infos.get(addr) {
                let line = format!("{} {} rating: {}", addr, user_agent, rating);
                list = list.push(Text::new(line).size(text_size));
            } else {
                list = list.push(Text::new(addr.to_string()).size(text_size));
            }
        }
        let list = scrollable(list).height(Length::Fill);

        Column::new()
            .spacing(text_size / 4)
            .push(objects)
            .push(addr_count)
            .push(incoming)
            .push(outgoing)
            .push(list)
            .into()
    }
}