koibumi-sync 0.0.1

An experimental Bitmessage client (sync version)
use crossbeam_channel::Sender;
use log::error;

use koibumi_common_sync::boxes::{Boxes, DEFAULT_USER_ID};
use koibumi_core::address::Address;
use koibumi_node_sync::Command as NodeCommand;

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

#[derive(Clone, Debug, Default)]
pub(crate) struct Tab {
    address_value: String,
}

impl Tab {
    // Draw the Ui.
    pub(crate) fn set_widgets(
        &mut self,
        ui: &mut conrod_core::UiCell,
        ids: &mut Ids,
        config: &GuiConfig,
        subscriptions: &[Address],
        boxes: &mut Option<Boxes>,
        command_sender: &mut Sender<NodeCommand>,
    ) {
        let text_size = config.text_size();
        let font_id = ui.fonts.ids().next().unwrap();

        if boxes.is_none() {
            return;
        }
        let boxes = boxes.as_mut().unwrap();

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

        let button_label = "Subscribe";
        let button_label_width = text::line::width(
            button_label,
            ui.fonts.get(font_id).unwrap(),
            text_size as u32,
        );
        widget::Canvas::new()
            .flow_down(&[
                (
                    ids.subscriptions_list_canvas,
                    widget::Canvas::new().pad_bottom(2.0),
                ),
                (
                    ids.subscriptions_input_canvas,
                    widget::Canvas::new()
                        .flow_right(&[
                            (
                                ids.subscriptions_edit_canvas,
                                widget::Canvas::new().pad_right(2.0),
                            ),
                            (
                                ids.subscriptions_button_canvas,
                                widget::Canvas::new()
                                    .length(button_label_width + 8.0 + 4.0)
                                    .pad_right(2.0),
                            ),
                        ])
                        .length((text_size as f64 + 8.0 + 4.0) * 1.0 + 4.0)
                        .pad_bottom(2.0),
                ),
            ])
            .top_left_of(ids.tabs_body)
            .wh_of(ids.tabs_body)
            .set(ids.subscriptions, ui);

        let (mut items, scrollbar) = widget::List::flow_down(subscriptions.len())
            .top_left_of(ids.subscriptions_list_canvas)
            .wh_of(ids.subscriptions_list_canvas)
            .item_size(text_size as f64 + 8.0)
            .scrollbar_on_top()
            .set(ids.subscriptions_list, ui);

        while let Some(item) = items.next(ui) {
            let i = item.i;
            let label = boxes.user().rich_alias(&subscriptions[i].to_string());
            let text = widget::Text::new(&label)
                .font_size(text_size as u32)
                .padded_w_of(ids.subscriptions_list_canvas, 2.0)
                .h(text_size as f64 + 8.0)
                .color(color::WHITE);
            item.set(text, ui);
        }

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

        widget::Canvas::new()
            .top_left_with_margins_on(ids.subscriptions_edit_canvas, 2.0, 2.0)
            .padded_w_of(ids.subscriptions_edit_canvas, 2.0)
            .h(text_size as f64 + 8.0)
            .scroll_kids_vertically()
            .color(color::LIGHT_GRAY)
            .set(ids.subscriptions_edit_canvas_inner, ui);

        if let Some(edit) = widget::TextEdit::new(&self.address_value)
            .top_left_with_margins_on(ids.subscriptions_edit_canvas_inner, 2.0, 2.0)
            .padded_w_of(ids.subscriptions_edit_canvas_inner, 2.0)
            .parent(ids.subscriptions_edit_canvas_inner)
            .restrict_to_height(false)
            .font_size(text_size as u32)
            .wrap_by_character()
            .color(color::BLACK)
            .line_spacing((text_size / 2) as f64)
            .set(ids.subscriptions_edit, ui)
        {
            self.address_value = edit;
        }

        widget::Scrollbar::y_axis(ids.subscriptions_edit_canvas_inner)
            .auto_hide(true)
            .set(ids.subscriptions_edit_scrollbar, ui);

        for _click in widget::Button::new()
            .top_left_with_margins_on(ids.subscriptions_button_canvas, 2.0, 2.0)
            .w_h(button_label_width + 8.0, text_size as f64 + 8.0)
            .label_font_size(text_size as u32)
            .label(button_label)
            .color(color::DARK_GRAY)
            .label_color(color::WHITE)
            .set(ids.subscriptions_button, ui)
        {
            let address = self.address_value.parse::<Address>();
            if let Err(err) = address {
                error!("{}", err);
                continue;
            }
            let address = address.unwrap();
            if boxes.user().subscriptions().contains(&address) {
                continue;
            }
            if let Err(err) = boxes.manager().subscribe(DEFAULT_USER_ID, &address) {
                error!("{}", err);
                continue;
            }
            if let Err(err) = command_sender.send(NodeCommand::Subscribe {
                id: DEFAULT_USER_ID.to_vec(),
                address: address.clone(),
            }) {
                error!("{}", err);
                continue;
            }
            boxes.user_mut().subscriptions_mut().push(address);
            self.address_value = String::new();
        }
    }
}