koibumi-sync 0.0.1

An experimental Bitmessage client (sync version)
use std::collections::HashMap;

use crate::{config::Config as GuiConfig, ids::Ids};

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

#[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 {
    // Draw the Ui.
    pub(crate) fn set_widgets(
        &mut self,
        ui: &mut conrod_core::UiCell,
        ids: &mut Ids,
        config: &GuiConfig,
    ) {
        let text_size = config.text_size();

        use conrod_core::{color, widget, Colorable, Positionable, Sizeable, Widget};

        widget::Canvas::new()
            .flow_down(&[
                (
                    ids.status_counts_canvas,
                    widget::Canvas::new()
                        .length(text_size as f64 / 2.0 * 13.0)
                        .scroll_kids_vertically()
                        .color(color::DARK_CHARCOAL)
                        .w_of(ids.tabs_body)
                        .pad_bottom(2.0),
                ),
                (
                    ids.status_peers_canvas,
                    widget::Canvas::new().w_of(ids.tabs_body),
                ),
            ])
            .top_left_of(ids.tabs_body)
            .wh_of(ids.tabs_body)
            .set(ids.status, ui);

        let objects = format!(
            "Objects: {} missing, {} loaded, {} uploaded",
            self.missing_objects, self.loaded_objects, self.uploaded_objects
        );
        let addresses = format!("{} addresses", self.addr_count);
        let incoming = format!(
            "Incoming: {} initiated, {} connected, {} established",
            self.incoming_initiated, self.incoming_connected, self.incoming_established
        );
        let outgoing = format!(
            "Outgoing: {} initiated, {} connected, {} established",
            self.outgoing_initiated, self.outgoing_connected, self.outgoing_established
        );
        let counts = format!("{}\n{}\n{}\n{}", objects, addresses, incoming, outgoing);
        widget::TextEdit::new(&counts)
            .top_left_with_margins_on(ids.status_counts_canvas, 2.0, 2.0)
            .padded_w_of(ids.status_counts_canvas, 2.0)
            .parent(ids.status_counts_canvas)
            .restrict_to_height(false)
            .font_size(text_size as u32)
            .line_spacing((text_size / 2) as f64)
            .set(ids.status_counts, ui);

        widget::Scrollbar::y_axis(ids.status_counts_canvas)
            .auto_hide(true)
            .set(ids.status_counts_scrollbar, ui);

        let (mut items, scrollbar) = widget::List::flow_down(self.peers.len())
            .top_left_with_margins_on(ids.status_peers_canvas, 2.0, 2.0)
            .padded_wh_of(ids.status_peers_canvas, 2.0)
            .item_size(text_size as f64 + 8.0)
            .scrollbar_on_top()
            .set(ids.status_peers, ui);

        while let Some(item) = items.next(ui) {
            let i = item.i;
            let addr = &self.peers[i];
            let label = if let Some((user_agent, rating)) = self.peer_infos.get(addr) {
                format!("{} {} rating: {}", addr, user_agent, rating)
            } else {
                addr.to_string()
            };
            let text = widget::Text::new(&label)
                .font_size(text_size as u32)
                .padded_w_of(ids.status_peers_canvas, 2.0)
                .color(color::WHITE)
                .h(text_size as f64 + 8.0);
            item.set(text, ui);
        }

        if let Some(s) = scrollbar {
            s.set(ui)
        }
    }
}