Compare commits
20 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
31bdb6d92e | |
|
|
83f4ee0e51 | |
|
|
ed1d2b5835 | |
|
|
324a7b07b0 | |
|
|
37566c4413 | |
|
|
787201c3a8 | |
|
|
6f8a76cb13 | |
|
|
0f4c567405 | |
|
|
d9300d80ff | |
|
|
72ae3121d4 | |
|
|
75149668ef | |
|
|
7e4b7b2080 | |
|
|
28d2a7cca9 | |
|
|
9a477c48cc | |
|
|
5598f39315 | |
|
|
ff2c41cf69 | |
|
|
21d8cfb185 | |
|
|
173bf045d9 | |
|
|
25e99fbf93 | |
|
|
6bbb9861ef |
|
|
@ -134,7 +134,7 @@ dependencies = [
|
|||
"log",
|
||||
"parking",
|
||||
"polling",
|
||||
"rustix 0.37.3",
|
||||
"rustix",
|
||||
"slab",
|
||||
"socket2",
|
||||
"waker-fn",
|
||||
|
|
@ -744,17 +744,6 @@ dependencies = [
|
|||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.2.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1"
|
||||
dependencies = [
|
||||
"errno-dragonfly",
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.3.0"
|
||||
|
|
@ -1301,19 +1290,6 @@ dependencies = [
|
|||
"want",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hyper-tls"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"hyper",
|
||||
"native-tls",
|
||||
"tokio",
|
||||
"tokio-native-tls",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iced"
|
||||
version = "0.8.0"
|
||||
|
|
@ -1556,12 +1532,6 @@ version = "0.5.6"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4"
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.3.0"
|
||||
|
|
@ -1697,24 +1667,6 @@ dependencies = [
|
|||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "native-tls"
|
||||
version = "0.2.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"log",
|
||||
"openssl",
|
||||
"openssl-probe",
|
||||
"openssl-sys",
|
||||
"schannel",
|
||||
"security-framework",
|
||||
"security-framework-sys",
|
||||
"tempfile",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ndk"
|
||||
version = "0.7.0"
|
||||
|
|
@ -1906,51 +1858,6 @@ version = "1.17.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3"
|
||||
|
||||
[[package]]
|
||||
name = "openssl"
|
||||
version = "0.10.48"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "518915b97df115dd36109bfa429a48b8f737bd05508cf9588977b599648926d2"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cfg-if",
|
||||
"foreign-types 0.3.2",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"openssl-macros",
|
||||
"openssl-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openssl-macros"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openssl-probe"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
|
||||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "666416d899cf077260dac8698d60a60b435a46d57e82acb1be3d0dad87284e5b"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cc",
|
||||
"libc",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ordered-float"
|
||||
version = "3.6.0"
|
||||
|
|
@ -2338,12 +2245,10 @@ dependencies = [
|
|||
"http",
|
||||
"http-body",
|
||||
"hyper",
|
||||
"hyper-tls",
|
||||
"ipnet",
|
||||
"js-sys",
|
||||
"log",
|
||||
"mime",
|
||||
"native-tls",
|
||||
"once_cell",
|
||||
"percent-encoding",
|
||||
"pin-project-lite",
|
||||
|
|
@ -2351,7 +2256,6 @@ dependencies = [
|
|||
"serde_json",
|
||||
"serde_urlencoded",
|
||||
"tokio",
|
||||
"tokio-native-tls",
|
||||
"tower-service",
|
||||
"url",
|
||||
"wasm-bindgen",
|
||||
|
|
@ -2366,20 +2270,6 @@ version = "1.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.36.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db4165c9963ab29e422d6c26fbc1d37f15bace6b2810221f9d925023480fcf0e"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"errno 0.2.8",
|
||||
"io-lifetimes",
|
||||
"libc",
|
||||
"linux-raw-sys 0.1.4",
|
||||
"windows-sys 0.45.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.37.3"
|
||||
|
|
@ -2387,10 +2277,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "62b24138615de35e32031d041a09032ef3487a616d901ca4db224e7d557efae2"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"errno 0.3.0",
|
||||
"errno",
|
||||
"io-lifetimes",
|
||||
"libc",
|
||||
"linux-raw-sys 0.3.0",
|
||||
"linux-raw-sys",
|
||||
"windows-sys 0.45.0",
|
||||
]
|
||||
|
||||
|
|
@ -2401,7 +2291,6 @@ dependencies = [
|
|||
"handlebars",
|
||||
"iced",
|
||||
"iced_futures",
|
||||
"iced_native",
|
||||
"reqwest",
|
||||
"serde",
|
||||
"serde_json",
|
||||
|
|
@ -2423,15 +2312,6 @@ dependencies = [
|
|||
"bytemuck",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "schannel"
|
||||
version = "0.1.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3"
|
||||
dependencies = [
|
||||
"windows-sys 0.42.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scoped-tls"
|
||||
version = "1.0.1"
|
||||
|
|
@ -2456,29 +2336,6 @@ dependencies = [
|
|||
"tiny-skia",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "security-framework"
|
||||
version = "2.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a332be01508d814fed64bf28f798a146d73792121129962fdf335bb3c49a4254"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"core-foundation",
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
"security-framework-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "security-framework-sys"
|
||||
version = "2.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "31c9bb296072e961fcbd8853511dd39c2d8be2deb1e17c6860b1d30732b323b4"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.158"
|
||||
|
|
@ -2711,19 +2568,6 @@ dependencies = [
|
|||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af18f7ae1acd354b992402e9ec5864359d693cd8a79dcbef59f76891701c1e95"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"fastrand",
|
||||
"redox_syscall",
|
||||
"rustix 0.36.11",
|
||||
"windows-sys 0.42.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.2.0"
|
||||
|
|
@ -2810,16 +2654,6 @@ dependencies = [
|
|||
"windows-sys 0.45.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-native-tls"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2"
|
||||
dependencies = [
|
||||
"native-tls",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-util"
|
||||
version = "0.7.7"
|
||||
|
|
@ -2987,12 +2821,6 @@ dependencies = [
|
|||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "vcpkg"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
||||
|
||||
[[package]]
|
||||
name = "vec_map"
|
||||
version = "0.8.2"
|
||||
|
|
@ -3201,7 +3029,7 @@ dependencies = [
|
|||
"js-sys",
|
||||
"log",
|
||||
"naga",
|
||||
"parking_lot 0.12.1",
|
||||
"parking_lot 0.11.2",
|
||||
"raw-window-handle 0.5.1",
|
||||
"smallvec",
|
||||
"static_assertions",
|
||||
|
|
@ -3227,7 +3055,7 @@ dependencies = [
|
|||
"fxhash",
|
||||
"log",
|
||||
"naga",
|
||||
"parking_lot 0.12.1",
|
||||
"parking_lot 0.11.2",
|
||||
"profiling",
|
||||
"raw-window-handle 0.5.1",
|
||||
"smallvec",
|
||||
|
|
@ -3263,7 +3091,7 @@ dependencies = [
|
|||
"metal",
|
||||
"naga",
|
||||
"objc",
|
||||
"parking_lot 0.12.1",
|
||||
"parking_lot 0.11.2",
|
||||
"profiling",
|
||||
"range-alloc",
|
||||
"raw-window-handle 0.5.1",
|
||||
|
|
|
|||
|
|
@ -8,9 +8,8 @@ edition = "2021"
|
|||
[dependencies]
|
||||
serde = { version = "1.0.156", features = ["derive"] }
|
||||
serde_yaml = "0.9.19"
|
||||
serde_json = "1"
|
||||
iced = "0.8.0"
|
||||
iced_native = "0.9.1"
|
||||
serde_json = { version = "1", default-features=false, features=["alloc"] }
|
||||
iced = { version = "0.8.0" }
|
||||
handlebars = "4"
|
||||
iced_futures = { version = "0.6.0", features = ["async-std"] }
|
||||
reqwest = { version = "0.11", features = ["blocking"] }
|
||||
iced_futures = { version = "0.6.0", default-features=false, features = ["async-std"] }
|
||||
reqwest = { version = "0.11", default-features=false, features = ["blocking"] }
|
||||
|
|
|
|||
|
|
@ -37,22 +37,17 @@ pub struct Device {
|
|||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct GUI {
|
||||
pub buttons: Buttons,
|
||||
pub press: PreSufFix,
|
||||
pub release: PreSufFix,
|
||||
pub format: Option<String>,
|
||||
pub release_prefix: String,
|
||||
pub format_keys: Option<String>,
|
||||
pub user: String,
|
||||
pub feedback: GUIFeedback,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub struct GUIFeedback {
|
||||
pub url: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct PreSufFix {
|
||||
pub prefix: String,
|
||||
pub suffix: String,
|
||||
pub url_read: Option<String>,
|
||||
pub url_say: Option<String>,
|
||||
pub url_send: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
|
|
@ -65,6 +60,7 @@ pub struct Buttons {
|
|||
pub b: String,
|
||||
pub x: String,
|
||||
pub y: String,
|
||||
pub start: String,
|
||||
pub l: String,
|
||||
pub r: String,
|
||||
}
|
||||
|
|
@ -125,19 +121,13 @@ fn build_config_std() -> Config {
|
|||
b: env::var("INPUT_GUI_BUTTON_B").unwrap_or(String::from("2")),
|
||||
x: env::var("INPUT_GUI_BUTTON_X").unwrap_or(String::from("3")),
|
||||
y: env::var("INPUT_GUI_BUTTON_Y").unwrap_or(String::from("4")),
|
||||
start: env::var("INPUT_GUI_BUTTON_START").unwrap_or(String::from("5")),
|
||||
l: env::var("INPUT_GUI_BUTTON_L").unwrap_or(String::from("q")),
|
||||
r: env::var("INPUT_GUI_BUTTON_R").unwrap_or(String::from("e")),
|
||||
},
|
||||
press: PreSufFix{
|
||||
prefix: env::var("INPUT_GUI_PRESS_PREFIX").unwrap_or(String::from("")),
|
||||
suffix: env::var("INPUT_GUI_PRESS_SUFFIX").unwrap_or(String::from("")),
|
||||
},
|
||||
release: PreSufFix{
|
||||
prefix: env::var("INPUT_GUI_RELEASE_PREFIX").unwrap_or(String::from("")),
|
||||
suffix: env::var("INPUT_GUI_RELEASE_SUFFIX").unwrap_or(String::from("")),
|
||||
},
|
||||
release_prefix: env::var("INPUT_GUI_RELEASE_PREFIX").unwrap_or(String::from("")),
|
||||
user: env::var("INPUT_GUI_USER").unwrap_or(String::from("me")),
|
||||
format: match env::var("INPUT_GUI_FORMAT") {
|
||||
format_keys: match env::var("INPUT_GUI_FORMAT") {
|
||||
Ok(x) => Some(x),
|
||||
Err(_) => match env::var("INPUT_GUI_FORMAT_V01").unwrap_or(String::from("false")) == String::from("true") {
|
||||
true => Some(String::from("{\"T\":{{ms}},\"U\":\"{{user}}\",\"Y\":\"{{pressed}}\",\"N\":\"{{released}}\"}")),
|
||||
|
|
@ -145,7 +135,15 @@ fn build_config_std() -> Config {
|
|||
},
|
||||
},
|
||||
feedback: GUIFeedback{
|
||||
url: match env::var("INPUT_GUI_FEEDBACK_URL") {
|
||||
url_read: match env::var("INPUT_GUI_FEEDBACK_URL_READ") {
|
||||
Ok(url) => Some(url),
|
||||
Err(_) => None,
|
||||
},
|
||||
url_say: match env::var("INPUT_GUI_FEEDBACK_URL_SAY") {
|
||||
Ok(url) => Some(url),
|
||||
Err(_) => None,
|
||||
},
|
||||
url_send: match env::var("INPUT_GUI_FEEDBACK_URL_SEND") {
|
||||
Ok(url) => Some(url),
|
||||
Err(_) => None,
|
||||
},
|
||||
|
|
|
|||
264
src/gui.rs
264
src/gui.rs
|
|
@ -1,11 +1,12 @@
|
|||
use iced::widget::{button, column, text};
|
||||
use iced::widget::{button, column, row, text};
|
||||
use iced::widget::text_input;
|
||||
use iced::executor;
|
||||
use iced::keyboard;
|
||||
use iced::subscription;
|
||||
use iced::{Alignment, Element, Application, Settings, Subscription, Theme, Command};
|
||||
use iced_futures::backend::native::async_std::time::every;
|
||||
use handlebars::Handlebars;
|
||||
use serde_json::json;
|
||||
use serde_json::{json, Value};
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
use std::thread;
|
||||
use reqwest;
|
||||
|
|
@ -27,21 +28,28 @@ pub fn main(cfg: GUI, output_stream: Box<dyn OutputStream>) -> iced::Result {
|
|||
id: def.id,
|
||||
text_multithreading: def.text_multithreading,
|
||||
try_opengles_first: def.try_opengles_first,
|
||||
window: def.window,
|
||||
window: iced::window::Settings{
|
||||
size: (300, 900),
|
||||
position: iced::window::Position::Specific(0, 0),
|
||||
..iced::window::Settings::default()
|
||||
},
|
||||
};
|
||||
Main::run(settings)
|
||||
}
|
||||
|
||||
struct Main {
|
||||
c: std::sync::mpsc::Receiver<String>,
|
||||
ntfy1: String,
|
||||
ntfy2: String,
|
||||
feedback_recv_c: std::sync::mpsc::Receiver<Feedback>,
|
||||
feedback_send_c: std::sync::mpsc::Sender<Feedback>,
|
||||
ntfy_from_client: String,
|
||||
ntfy_from_server: String,
|
||||
configuring: Option<Message>,
|
||||
inputs: Inputs,
|
||||
keys_newly_down: Vec<iced::keyboard::KeyCode>,
|
||||
keys_already_down: Vec<iced::keyboard::KeyCode>,
|
||||
keys_up: Vec<iced::keyboard::KeyCode>,
|
||||
flags: Flags,
|
||||
input_text_entry_instruction: String,
|
||||
input_text_entry_value: String,
|
||||
}
|
||||
|
||||
struct Flags {
|
||||
|
|
@ -55,6 +63,7 @@ struct Inputs {
|
|||
b: iced::keyboard::KeyCode,
|
||||
x: iced::keyboard::KeyCode,
|
||||
y: iced::keyboard::KeyCode,
|
||||
start: iced::keyboard::KeyCode,
|
||||
l: iced::keyboard::KeyCode,
|
||||
r: iced::keyboard::KeyCode,
|
||||
}
|
||||
|
|
@ -68,8 +77,11 @@ struct Stick {
|
|||
|
||||
#[derive(Debug, Clone)]
|
||||
enum Message {
|
||||
EventOccurred(iced_native::Event),
|
||||
EventOccurred(iced::Event),
|
||||
Tick,
|
||||
InputTextEntryUpdate(String),
|
||||
InputTextEntrySubmitSay,
|
||||
InputTextEntrySubmitSend,
|
||||
Up,
|
||||
Down,
|
||||
Left,
|
||||
|
|
@ -78,10 +90,18 @@ enum Message {
|
|||
B,
|
||||
X,
|
||||
Y,
|
||||
Start,
|
||||
L,
|
||||
R,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
enum Feedback {
|
||||
Heard(String),
|
||||
Say(String),
|
||||
Send(String),
|
||||
}
|
||||
|
||||
fn controller_button_to_string(btn: Message, cur: iced::keyboard::KeyCode) -> String {
|
||||
return format!("{:?} => {:?}", cur, btn);
|
||||
}
|
||||
|
|
@ -97,12 +117,24 @@ impl Main {
|
|||
_ if key_code == &self.inputs.b => Some(&self.flags.cfg.buttons.b),
|
||||
_ if key_code == &self.inputs.x => Some(&self.flags.cfg.buttons.x),
|
||||
_ if key_code == &self.inputs.y => Some(&self.flags.cfg.buttons.y),
|
||||
_ if key_code == &self.inputs.start => Some(&self.flags.cfg.buttons.start),
|
||||
_ if key_code == &self.inputs.l => Some(&self.flags.cfg.buttons.l),
|
||||
_ if key_code == &self.inputs.r => Some(&self.flags.cfg.buttons.r),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn send_from_client(&mut self, text: Feedback) {
|
||||
match text.clone() {
|
||||
Feedback::Say(s) | Feedback::Send(s) if s.len() > 0 && s.len() < 1000 => {},
|
||||
_ => return,
|
||||
};
|
||||
match self.feedback_send_c.send(text) {
|
||||
Ok(_) => {},
|
||||
Err(err) => eprintln!("main.send_say() failed to enqueue: {}", err),
|
||||
};
|
||||
}
|
||||
|
||||
fn exchange(&mut self) {
|
||||
self.exchange_send();
|
||||
self.exchange_recv();
|
||||
|
|
@ -110,11 +142,16 @@ impl Main {
|
|||
|
||||
fn exchange_recv(&mut self) {
|
||||
loop {
|
||||
match self.c.try_recv() {
|
||||
match self.feedback_recv_c.try_recv() {
|
||||
Ok(msg) => {
|
||||
self.ntfy2 = msg
|
||||
match msg {
|
||||
Feedback::Heard(msg) => {
|
||||
self.ntfy_from_server = msg;
|
||||
},
|
||||
_ => break,
|
||||
};
|
||||
},
|
||||
_ => return,
|
||||
_ => break,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -124,15 +161,9 @@ impl Main {
|
|||
for key_code in self.keys_newly_down.iter() {
|
||||
match self.key_code_to_string(key_code) {
|
||||
Some(x) => {
|
||||
for c in self.flags.cfg.press.prefix.chars() {
|
||||
s.push(c);
|
||||
}
|
||||
for c in x.chars() {
|
||||
s.push(c);
|
||||
}
|
||||
for c in self.flags.cfg.press.suffix.chars() {
|
||||
s.push(c);
|
||||
}
|
||||
self.keys_already_down.push(*key_code);
|
||||
},
|
||||
None => {},
|
||||
|
|
@ -144,34 +175,34 @@ impl Main {
|
|||
match self.key_code_to_string(key_code) {
|
||||
Some(x) => {
|
||||
for c in x.chars() {
|
||||
for c in self.flags.cfg.release.prefix.chars() {
|
||||
for c in self.flags.cfg.release_prefix.chars() {
|
||||
t.push(c);
|
||||
}
|
||||
t.push(c);
|
||||
for c in self.flags.cfg.release.suffix.chars() {
|
||||
t.push(c);
|
||||
}
|
||||
}
|
||||
},
|
||||
None => {},
|
||||
};
|
||||
}
|
||||
if t.len() + s.len() > 0 {
|
||||
self.flags.output_stream.put(self.sprintf(s, t));
|
||||
self.flags.output_stream.put(self.sprintf_pressed_released(s, t));
|
||||
}
|
||||
self.keys_up.clear();
|
||||
}
|
||||
|
||||
fn sprintf(&self, pressed: Vec<char>, released: Vec<char>) -> Vec<char> {
|
||||
match self.flags.cfg.format.clone() {
|
||||
fn sprintf(&self, format: &String, content: &Value) -> Vec<char> {
|
||||
return Handlebars::new().render_template(format, content).unwrap().chars().collect();
|
||||
}
|
||||
|
||||
fn sprintf_pressed_released(&self, pressed: Vec<char>, released: Vec<char>) -> Vec<char> {
|
||||
match self.flags.cfg.format_keys.clone() {
|
||||
Some(x) => {
|
||||
let reg = Handlebars::new();
|
||||
return reg.render_template(&x, &json!({
|
||||
return self.sprintf(&x, &json!({
|
||||
"pressed": pressed.iter().collect::<String>(),
|
||||
"released": released.iter().collect::<String>(),
|
||||
"ms": SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_millis(),
|
||||
"user": self.flags.cfg.user,
|
||||
})).unwrap().chars().collect();
|
||||
}));
|
||||
},
|
||||
None => {
|
||||
let mut combo = vec![];
|
||||
|
|
@ -190,18 +221,21 @@ impl Application for Main {
|
|||
type Executor = executor::Default;
|
||||
|
||||
fn new(flags: Self::Flags) -> (Self, Command<Message>) {
|
||||
let (sender, receiver) = std::sync::mpsc::channel();
|
||||
let (sender1, receiver1) = std::sync::mpsc::channel();
|
||||
let (sender2, receiver2) = std::sync::mpsc::channel();
|
||||
let feedback_cfg = flags.cfg.feedback.clone();
|
||||
thread::spawn(move || {
|
||||
Feedback{
|
||||
c: sender,
|
||||
Feedbacker{
|
||||
send_c: sender1,
|
||||
recv_c: receiver2,
|
||||
cfg: feedback_cfg,
|
||||
}.listen()
|
||||
});
|
||||
return (Self {
|
||||
c: receiver,
|
||||
ntfy1: String::from(":wave:"),
|
||||
ntfy2: String::from(""),
|
||||
feedback_send_c: sender2,
|
||||
feedback_recv_c: receiver1,
|
||||
ntfy_from_client: String::from(" "),
|
||||
ntfy_from_server: String::from(" "),
|
||||
configuring: None,
|
||||
inputs: Inputs{
|
||||
stick: Stick {
|
||||
|
|
@ -214,6 +248,7 @@ impl Application for Main {
|
|||
b: iced::keyboard::KeyCode::Key2,
|
||||
x: iced::keyboard::KeyCode::Key3,
|
||||
y: iced::keyboard::KeyCode::Key4,
|
||||
start: iced::keyboard::KeyCode::Key5,
|
||||
l: iced::keyboard::KeyCode::Q,
|
||||
r: iced::keyboard::KeyCode::E,
|
||||
},
|
||||
|
|
@ -221,6 +256,8 @@ impl Application for Main {
|
|||
keys_newly_down: vec![],
|
||||
keys_already_down: vec![],
|
||||
keys_up: vec![],
|
||||
input_text_entry_instruction: String::from(""),
|
||||
input_text_entry_value: String::from(""),
|
||||
}, Command::none())
|
||||
}
|
||||
|
||||
|
|
@ -233,6 +270,17 @@ impl Application for Main {
|
|||
Message::Tick => {
|
||||
self.exchange();
|
||||
},
|
||||
Message::InputTextEntryUpdate(payload) => {
|
||||
self.input_text_entry_value = payload;
|
||||
},
|
||||
Message::InputTextEntrySubmitSend => {
|
||||
self.send_from_client(Feedback::Send(self.input_text_entry_value.clone()));
|
||||
self.input_text_entry_value = String::from("");
|
||||
},
|
||||
Message::InputTextEntrySubmitSay => {
|
||||
self.send_from_client(Feedback::Say(self.input_text_entry_value.clone()));
|
||||
self.input_text_entry_value = String::from("");
|
||||
},
|
||||
Message::EventOccurred(event) if self.configuring.is_some() => {
|
||||
match event {
|
||||
iced::event::Event::Keyboard(keyboard::Event::KeyPressed{
|
||||
|
|
@ -249,11 +297,12 @@ impl Application for Main {
|
|||
Message::B => { self.inputs.b = key_code },
|
||||
Message::X => { self.inputs.x = key_code },
|
||||
Message::Y => { self.inputs.y = key_code },
|
||||
Message::Start => { self.inputs.start = key_code },
|
||||
Message::L => { self.inputs.l = key_code },
|
||||
Message::R => { self.inputs.r = key_code },
|
||||
_ => {},
|
||||
};
|
||||
self.ntfy1 = format!("{:?} => {:?}", key_code.clone(), self.configuring.as_ref().unwrap());
|
||||
self.ntfy_from_client = format!("{:?} => {:?}", key_code.clone(), self.configuring.as_ref().unwrap());
|
||||
self.configuring = None;
|
||||
},
|
||||
_ => {},
|
||||
|
|
@ -300,7 +349,7 @@ impl Application for Main {
|
|||
},
|
||||
_ => {
|
||||
self.configuring = Some(msg.clone());
|
||||
self.ntfy1 = format!("push a key to bind to {:?}", msg.clone());
|
||||
self.ntfy_from_client = format!("push a key to bind to {:?}", msg.clone());
|
||||
},
|
||||
}
|
||||
return Command::none();
|
||||
|
|
@ -308,70 +357,149 @@ impl Application for Main {
|
|||
|
||||
fn subscription(&self) -> Subscription<Message> {
|
||||
return subscription::Subscription::batch(vec![
|
||||
subscription::events_with(|event, _| match event {
|
||||
iced::Event::Keyboard(_) => Some(Message::EventOccurred(event)),
|
||||
subscription::events_with(|event, status| match status {
|
||||
iced::event::Status::Ignored => match event {
|
||||
iced::Event::Keyboard(_) => Some(Message::EventOccurred(event)),
|
||||
_ => None,
|
||||
},
|
||||
_ => None,
|
||||
}),
|
||||
every(std::time::Duration::from_millis(5000)).map(|_| Message::Tick),
|
||||
every(std::time::Duration::from_millis(2000)).map(|_| Message::Tick),
|
||||
]);
|
||||
}
|
||||
|
||||
fn view(&self) -> Element<Message> {
|
||||
let new_cfg_button = |msg: Message, s| button(text(controller_button_to_string(msg.clone(), s))).on_press(msg.clone());
|
||||
return column![
|
||||
button(text(controller_button_to_string(Message::Up, self.inputs.stick.up))).on_press(Message::Up),
|
||||
button(text(controller_button_to_string(Message::Down, self.inputs.stick.down))).on_press(Message::Down),
|
||||
button(text(controller_button_to_string(Message::Left, self.inputs.stick.left))).on_press(Message::Left),
|
||||
button(text(controller_button_to_string(Message::Right, self.inputs.stick.right))).on_press(Message::Right),
|
||||
button(text(controller_button_to_string(Message::A, self.inputs.a))).on_press(Message::A),
|
||||
button(text(controller_button_to_string(Message::B, self.inputs.b))).on_press(Message::B),
|
||||
button(text(controller_button_to_string(Message::X, self.inputs.x))).on_press(Message::X),
|
||||
button(text(controller_button_to_string(Message::Y, self.inputs.y))).on_press(Message::Y),
|
||||
button(text(controller_button_to_string(Message::L, self.inputs.l))).on_press(Message::L),
|
||||
button(text(controller_button_to_string(Message::R, self.inputs.r))).on_press(Message::R),
|
||||
text(self.ntfy1.clone()).size(50),
|
||||
text(self.ntfy2.clone()).size(50),
|
||||
]
|
||||
.padding(20)
|
||||
.align_items(Alignment::Center)
|
||||
.into();
|
||||
text(String::from("= MAYHEM PARTY =")).size(32),
|
||||
column![
|
||||
column![
|
||||
text(String::from("Button Mapping")).size(24),
|
||||
text(String::from("--------------")).size(24),
|
||||
row![
|
||||
column![
|
||||
new_cfg_button(Message::Up, self.inputs.stick.up),
|
||||
new_cfg_button(Message::Down, self.inputs.stick.down),
|
||||
new_cfg_button(Message::Left, self.inputs.stick.left),
|
||||
new_cfg_button(Message::Right, self.inputs.stick.right),
|
||||
new_cfg_button(Message::Start, self.inputs.start),
|
||||
].padding(5).align_items(Alignment::Center),
|
||||
column![
|
||||
new_cfg_button(Message::A, self.inputs.a),
|
||||
new_cfg_button(Message::B, self.inputs.b),
|
||||
new_cfg_button(Message::X, self.inputs.x),
|
||||
new_cfg_button(Message::Y, self.inputs.y),
|
||||
new_cfg_button(Message::L, self.inputs.l),
|
||||
new_cfg_button(Message::R, self.inputs.r),
|
||||
].padding(5).align_items(Alignment::Center),
|
||||
].padding(5).align_items(Alignment::Center),
|
||||
text(String::from("--------------")).size(24),
|
||||
text(self.ntfy_from_client.clone()).size(18),
|
||||
].padding(20).align_items(Alignment::Center),
|
||||
column![
|
||||
text_input(
|
||||
&self.input_text_entry_instruction,
|
||||
&self.input_text_entry_value,
|
||||
Message::InputTextEntryUpdate
|
||||
),
|
||||
row![
|
||||
button(text("Say")).on_press(Message::InputTextEntrySubmitSay).padding(20),
|
||||
button(text("Send")).on_press(Message::InputTextEntrySubmitSend).padding(20),
|
||||
].padding(20).align_items(Alignment::Center),
|
||||
text(self.ntfy_from_server.clone().trim()).size(18),
|
||||
].padding(20).align_items(Alignment::Center),
|
||||
].padding(0).align_items(Alignment::Center),
|
||||
].padding(0).align_items(Alignment::Center).into();
|
||||
}
|
||||
}
|
||||
|
||||
struct Feedback {
|
||||
c: std::sync::mpsc::Sender<String>,
|
||||
struct Feedbacker {
|
||||
send_c: std::sync::mpsc::Sender<Feedback>,
|
||||
recv_c: std::sync::mpsc::Receiver<Feedback>,
|
||||
cfg: GUIFeedback,
|
||||
}
|
||||
|
||||
impl Feedback {
|
||||
impl Feedbacker {
|
||||
fn listen(&mut self) {
|
||||
loop {
|
||||
std::thread::sleep(std::time::Duration::from_secs(2));
|
||||
match self.read() {
|
||||
match self.read_from_server() {
|
||||
Some(msg) if msg.len() > 0 => {
|
||||
self.write(msg.clone());
|
||||
self.write_from_server(msg.clone());
|
||||
},
|
||||
_ => {},
|
||||
};
|
||||
match self.read_from_client() {
|
||||
Some(msg) => self.write_from_client(msg.clone()),
|
||||
_ => {},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
fn read(&mut self) -> Option<String> {
|
||||
return match &self.cfg.url {
|
||||
Some(url) => match reqwest::blocking::get(url) {
|
||||
Ok(resp) => match resp.text() {
|
||||
Ok(text) => Some(text),
|
||||
_ => None,
|
||||
},
|
||||
_ => None,
|
||||
fn read_from_server(&mut self) -> Option<String> {
|
||||
return match &self.cfg.url_read {
|
||||
Some(url) => {
|
||||
match reqwest::blocking::get(url) {
|
||||
Ok(resp) => match resp.text() {
|
||||
Ok(text) => Some(text),
|
||||
_ => None,
|
||||
},
|
||||
Err(err) => {
|
||||
eprintln!("feedback.read: cannot fetch: {}", err);
|
||||
None
|
||||
},
|
||||
}
|
||||
},
|
||||
_ => None,
|
||||
};
|
||||
}
|
||||
|
||||
fn write(&mut self, msg: String) {
|
||||
match self.c.send(msg.clone()) {
|
||||
fn write_from_server(&mut self, msg: String) {
|
||||
match self.send_c.send(Feedback::Heard(msg.clone())) {
|
||||
Ok(_) => {},
|
||||
Err(err) => eprintln!("feedback.listen() failed to display {}: {}", msg, err),
|
||||
};
|
||||
}
|
||||
|
||||
fn read_from_client(&mut self) -> Option<Feedback> {
|
||||
let mut last: Option<Feedback> = None;
|
||||
loop {
|
||||
match self.recv_c.try_recv() {
|
||||
Ok(msg) => {
|
||||
last = Some(msg);
|
||||
},
|
||||
_ => break,
|
||||
};
|
||||
}
|
||||
return last;
|
||||
}
|
||||
|
||||
fn write_from_client(&mut self, msg: Feedback) {
|
||||
match msg {
|
||||
Feedback::Send(send) if send.len() > 0 => match &self.cfg.url_send {
|
||||
Some(url) => {
|
||||
match reqwest::blocking::get(format!("{}{}", url, send)) {
|
||||
Err(err) => {
|
||||
eprintln!("feedback.write_from_client: cannot send: {}", err);
|
||||
},
|
||||
_ => {},
|
||||
};
|
||||
},
|
||||
_ => {},
|
||||
},
|
||||
Feedback::Say(say) if say.len() > 0 => match &self.cfg.url_say {
|
||||
Some(url) => {
|
||||
match reqwest::blocking::get(format!("{}{}", url, say)) {
|
||||
Err(err) => {
|
||||
eprintln!("feedback.write_from_client: cannot say: {}", err);
|
||||
},
|
||||
_ => {},
|
||||
};
|
||||
},
|
||||
_ => {},
|
||||
},
|
||||
_ => {},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
)
|
||||
|
|
@ -8,7 +10,13 @@ import (
|
|||
func main() {
|
||||
p := os.Getenv("PORT")
|
||||
if err := http.ListenAndServe(":"+p, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte(os.Getenv("BODY")))
|
||||
b, _ := io.ReadAll(r.Body)
|
||||
log.Printf("> %s (%+v) %s", r.URL, r.Header, b)
|
||||
body := os.Getenv("BODY")
|
||||
if body == "-" {
|
||||
body = string(b)
|
||||
}
|
||||
w.Write([]byte(body))
|
||||
})); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue