rustyproxy 1.1.9

GUI for the rustyproxy project
Documentation
use crate::app::backend::apiutils;
use crate::app::backend::dbutils::Note;
use crate::app::mods::inspector::{code_edit_ui, code_view_ui};

use poll_promise::Promise;

#[derive(Default, serde::Deserialize, serde::Serialize)]
pub struct NoteViewer {
    note: Note,
    is_minimized: bool,
    is_new: bool,
    #[serde(skip)]
    server_promise: Option<Promise<Result<String, reqwest::Error>>>,
    active_window: ActiveNoteViewerMenu,
    is_active: bool,
}

#[derive(Default, Debug)]
pub struct Notes {
    items: Vec<NoteViewer>,
    selected: usize,
    api_addr: Option<String>,
    api_port: Option<usize>,
    api_secret: Option<String>,
}

impl Notes {
    pub fn new(
        api_addr: Option<String>,
        api_port: Option<usize>,
        api_secret: Option<String>,
    ) -> Self {
        Self {
            api_addr,
            api_port,
            api_secret,
            ..Default::default()
        }
    }

    pub fn display(&mut self, ui: &mut egui::Ui) {
        egui::menu::bar(ui, |ui| {
            for idx in 0..self.items.len() {
                if ui
                    .selectable_label(idx == self.selected, idx.to_string())
                    .clicked()
                {
                    self.selected = idx;
                }
                ui.separator();
            }
        });
        ui.separator();

        let api_addr = self.api_addr.clone();
        let api_port = self.api_port.clone();
        let api_secret = self.api_secret.clone().unwrap();

        let api_url = format!("{}:{}", api_addr.unwrap(), api_port.unwrap());
        if let Some(noteviewer) = self.items.get_mut(self.selected) {
            noteviewer.display(ui, &api_url, &api_secret);
        }
    }

    pub fn extend_from_slice(&mut self, other: &[Note]) {
        for note in other.iter() {
            self.items.push(NoteViewer::from_note(note, true));
        }
    }
}

#[derive(serde::Deserialize, serde::Serialize, PartialEq)]
pub enum ActiveNoteViewerMenu {
    Viewer,
    Editor,
}

impl Default for ActiveNoteViewerMenu {
    fn default() -> Self {
        Self::Viewer
    }
}

impl std::fmt::Debug for NoteViewer {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
        write!(f, "{:?}", self.note)?;
        Ok(())
    }
}

impl NoteViewer {
    pub fn from_note(note: &Note, is_new: bool) -> Self {
        Self {
            note: note.clone(),
            is_new,
            is_minimized: false,
            server_promise: None,
            active_window: ActiveNoteViewerMenu::Viewer,
            is_active: true,
        }
    }

    pub fn note(&self) -> &Note {
        &self.note
    }

    pub fn server_promise_mut(&mut self) -> &mut Option<Promise<Result<String, reqwest::Error>>> {
        &mut self.server_promise
    }

    pub fn is_minimized(&self) -> bool {
        self.is_minimized
    }

    pub fn toggle_is_minimized(&mut self) {
        self.is_minimized = !self.is_minimized;
    }

    pub fn active_window(&self) -> &ActiveNoteViewerMenu {
        &self.active_window
    }

    pub fn set_active_window(&mut self, active_window: ActiveNoteViewerMenu) {
        self.active_window = active_window;
    }

    pub fn note_mut(&mut self) -> &mut Note {
        &mut self.note
    }

    pub fn is_new(&self) -> bool {
        self.is_new
    }

    pub fn is_active(&self) -> bool {
        self.is_active
    }

    pub fn display(&mut self, ui: &mut egui::Ui, url: &str, api_secret: &str) {
        egui::menu::bar(ui, |ui| {
            if ui
                .selectable_label(
                    self.active_window() == &ActiveNoteViewerMenu::Viewer,
                    "☰ Viewer",
                )
                .clicked()
            {
                self.set_active_window(ActiveNoteViewerMenu::Viewer);
            }
            ui.separator();
            if ui
                .selectable_label(
                    self.active_window() == &ActiveNoteViewerMenu::Editor,
                    "☰ Editor",
                )
                .clicked()
            {
                self.set_active_window(ActiveNoteViewerMenu::Editor);
            }
            ui.separator();
            if ui.button("✉ Push to server").clicked() {
                /* send to server */
                let u = url.to_owned();
                let secret = api_secret.to_owned();
                let note = self.note().clone();
                let is_new = self.is_new();
                self.server_promise_mut().get_or_insert_with(|| {
                    return Promise::spawn_thread("note_push", move || {
                        apiutils::push_note_to_api(&u, &secret, &note, is_new)
                    });
                });
            }
            ui.separator();
            if ui.button("✉ Push as new").clicked() {
                /* send to server */
                let u = url.to_owned();
                let secret = api_secret.to_owned();
                let mut note = self.note().clone();
                note.set_id(0);
                let is_new = true;
                self.server_promise_mut().get_or_insert_with(|| {
                    return Promise::spawn_thread("note_push", move || {
                        apiutils::push_note_to_api(&u, &secret, &note, is_new)
                    });
                });
            }
            ui.separator();
            ui.label("title:");
            ui.text_edit_singleline(self.note_mut().title_mut());
            ui.with_layout(egui::Layout::top_down(egui::Align::RIGHT), |ui| {
                ui.horizontal(|ui| {
                    if ui.button("x").clicked() {
                        self.is_active = false;
                        ui.ctx().request_repaint();
                    }
                    ui.separator();
                    let bt = if self.is_minimized() { "+" } else { "-" };
                    if ui.button(bt).clicked() {
                        self.toggle_is_minimized();
                        ui.ctx().request_repaint();
                    }
                    ui.separator();
                });
            });
        });
        ui.separator();
        if !self.is_minimized() {
            match self.active_window() {
                ActiveNoteViewerMenu::Viewer => {
                    code_view_ui(ui, self.note().body());
                }
                ActiveNoteViewerMenu::Editor => {
                    code_edit_ui(ui, self.note_mut().body_mut());
                }
            }
        }
    }
}