feat: Add hyperdeck command

This commit is contained in:
2024-05-20 23:04:47 +01:00
parent ee375e34a8
commit f9cac35a29
14 changed files with 1122 additions and 174 deletions
+3
View File
@@ -1,3 +1,6 @@
# Copied during build (🤮)
src/websocket.rs
# trunk output folder
dist
+2 -1
View File
@@ -9,12 +9,13 @@ eframe = { version = "0.27.0", default-features = false, features = [
"accesskit", # Make egui comptaible with screen readers.
"default_fonts", # Embed the default egui fonts.
"glow", # Use the glow rendering backend. Alternative: "wgpu".
"persistence", # Enable restoring app state when restarting the app.
] }
log = "0.4"
serde = { version = "1", features = ["derive"] }
hrtime = "0.2.0"
wasm-timer = "0.2.5"
ewebsock = "0.5.0"
serde_json = "1.0.117"
# native:
+7
View File
@@ -0,0 +1,7 @@
fn main() {
// Sorry, I know it's horrible but I don't have the spoons to make it right.
const API_DEFINITION_FILE: &str = "../monitor/src/api/message.rs";
println!("cargo:rerun-if-changed={API_DEFINITION_FILE}");
std::fs::copy(API_DEFINITION_FILE, "./src/websocket.rs")
.expect("Failed to copy API definition");
}
+44 -29
View File
@@ -1,35 +1,38 @@
use std::{
collections::VecDeque,
fmt::Display,
mem,
net::{IpAddr, Ipv4Addr},
};
use egui::{Color32, RichText, Sense, Stroke, Vec2};
use egui::{Button, Color32, RichText, Sense, Stroke, Vec2};
use ewebsock::{Options, WsReceiver, WsSender};
use wasm_timer::Instant;
#[derive(serde::Deserialize, serde::Serialize)]
#[serde(default)]
use crate::websocket::{AddHyperdeckRequest, ClientRequest};
pub struct HyperdeckMonitorApp {
#[serde(skip)]
blink: bool,
#[serde(skip)]
last_blink_change: Instant,
#[serde(skip)]
new_hyperdeck_ip: String,
#[serde(skip)]
new_hyperdeck_name: String,
#[serde(skip)]
new_hyperdeck_port: String,
hyperdecks: Vec<Hyperdeck>,
websocket_message_queue: VecDeque<ClientRequest>,
ws_sender: WsSender,
ws_receiver: WsReceiver,
}
impl Default for HyperdeckMonitorApp {
fn default() -> Self {
let (ws_sender, ws_receiver) =
ewebsock::connect("ws://127.0.0.1:9681/ws", Options::default()).unwrap();
Self {
blink: false,
last_blink_change: Instant::now(),
new_hyperdeck_ip: "".to_owned(),
new_hyperdeck_name: "".to_owned(),
new_hyperdeck_port: 9993.to_string(),
hyperdecks: vec![
Hyperdeck {
name: "Test Hyperdeck 1".to_string(),
@@ -52,27 +55,20 @@ impl Default for HyperdeckMonitorApp {
}],
},
],
websocket_message_queue: VecDeque::new(),
ws_sender,
ws_receiver,
}
}
}
impl HyperdeckMonitorApp {
pub fn new(cc: &eframe::CreationContext<'_>) -> Self {
// Load previous app state (if any)
if let Some(storage) = cc.storage {
return eframe::get_value(storage, eframe::APP_KEY).unwrap_or_default();
}
Default::default()
}
}
impl eframe::App for HyperdeckMonitorApp {
fn save(&mut self, storage: &mut dyn eframe::Storage) {
eframe::set_value(storage, eframe::APP_KEY, self);
}
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
if let Some(message) = self.websocket_message_queue.pop_front() {
self.ws_sender.send(ewebsock::WsMessage::Text(
serde_json::to_string(&message).expect("Could not serialize message"),
));
}
egui::TopBottomPanel::top("top_panel").show(ctx, |ui| {
egui::menu::bar(ui, |ui| {
egui::widgets::global_dark_light_mode_buttons(ui);
@@ -80,7 +76,13 @@ impl eframe::App for HyperdeckMonitorApp {
});
egui::CentralPanel::default().show(ctx, |ui| {
add_hyperdeck_panel(ui, &mut self.new_hyperdeck_ip, &mut self.new_hyperdeck_name);
add_hyperdeck_panel(
ui,
&mut self.new_hyperdeck_name,
&mut self.new_hyperdeck_ip,
&mut self.new_hyperdeck_port,
&mut self.websocket_message_queue,
);
ui.separator();
ui.vertical(|ui| {
@@ -105,8 +107,10 @@ impl eframe::App for HyperdeckMonitorApp {
fn add_hyperdeck_panel(
ui: &mut egui::Ui,
new_hyperdeck_ip: &mut String,
new_hyperdeck_name: &mut String,
new_hyperdeck_ip: &mut String,
new_hyperdeck_port: &mut String,
message_queue: &mut VecDeque<ClientRequest>,
) {
ui.heading("Add hyperdeck");
ui.horizontal(|ui| {
@@ -114,8 +118,19 @@ fn add_hyperdeck_panel(
ui.text_edit_singleline(new_hyperdeck_name);
ui.label("IP");
ui.text_edit_singleline(new_hyperdeck_ip);
if ui.button("Add").clicked() {
// Do Something
ui.label("Port");
ui.text_edit_singleline(new_hyperdeck_port);
let button_enabled = new_hyperdeck_ip.parse::<IpAddr>().is_ok()
&& !new_hyperdeck_name.is_empty()
&& new_hyperdeck_port.parse::<u16>().is_ok();
if ui.add_enabled(button_enabled, Button::new("Add")).clicked() {
message_queue.push_back(ClientRequest::AddHyperdeck(AddHyperdeckRequest {
name: mem::take(new_hyperdeck_name),
ip: mem::take(new_hyperdeck_ip),
port: mem::replace(new_hyperdeck_port, "9993".to_string())
.parse::<u16>()
.unwrap(),
}));
}
});
}
+2
View File
@@ -1,2 +1,4 @@
mod app;
mod websocket;
pub use app::HyperdeckMonitorApp;
+2 -2
View File
@@ -11,7 +11,7 @@ fn main() -> eframe::Result<()> {
eframe::run_native(
"eframe template",
native_options,
Box::new(|cc| Box::new(hyperdeck_monitor_gui::HyperdeckMonitorApp::new(cc))),
Box::new(|_| Box::new(hyperdeck_monitor_gui::HyperdeckMonitorApp::default())),
)
}
@@ -26,7 +26,7 @@ fn main() {
.start(
"the_canvas_id", // Where to draw to.
web_options,
Box::new(|cc| Box::new(hyperdeck_monitor_gui::HyperdeckMonitorApp::new(cc))),
Box::new(|_| Box::new(hyperdeck_monitor_gui::HyperdeckMonitorApp::default())),
)
.await
.expect("failed to start eframe");