feat: dynamic app catalog, Gitea app polish, registry sync
App catalog served from Gitea repos (app-catalog) with 35 apps. Nodes fetch catalog dynamically — new apps appear without frontend rebuild. Test app added and removed to verify pipeline. Gitea manifest updated with internal_port/nginx_proxy for iframe. Updated catalog.json, nginx configs, app session configs. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
1147dbd882
commit
3078d4b69e
@@ -4,7 +4,6 @@ use hyper::{Request, Response};
|
||||
use hyper_ws_listener::WsStream;
|
||||
use serde::Deserialize;
|
||||
use std::time::Instant;
|
||||
use tokio::process::Command;
|
||||
use tokio::sync::broadcast;
|
||||
use tokio_tungstenite::tungstenite::Message;
|
||||
use tracing::{debug, info, warn};
|
||||
@@ -72,21 +71,9 @@ enum InputCommand {
|
||||
Ping,
|
||||
}
|
||||
|
||||
async fn xdotool(args: &[&str]) -> Result<()> {
|
||||
let output = Command::new("xdotool")
|
||||
.env("DISPLAY", ":0")
|
||||
.args(args)
|
||||
.output()
|
||||
.await
|
||||
.context("xdotool execution failed")?;
|
||||
|
||||
if !output.status.success() {
|
||||
let stderr = String::from_utf8_lossy(&output.stderr);
|
||||
debug!("xdotool error: {}", stderr);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Validate and acknowledge input — relay-only, no xdotool.
|
||||
/// All input is forwarded to browser clients via the broadcast channel;
|
||||
/// the browser's remote-relay.ts dispatches DOM events from there.
|
||||
async fn handle_input(msg: &str) -> Result<Option<String>> {
|
||||
let cmd: InputCommand = serde_json::from_str(msg)
|
||||
.context("invalid input command")?;
|
||||
@@ -97,25 +84,16 @@ async fn handle_input(msg: &str) -> Result<Option<String>> {
|
||||
warn!("rejected key: {}", k);
|
||||
return Ok(Some(r#"{"t":"e","m":"invalid key"}"#.to_string()));
|
||||
}
|
||||
xdotool(&["key", "--clearmodifiers", k]).await?;
|
||||
}
|
||||
InputCommand::MouseMove { x, y } => {
|
||||
let x = x.clamp(-50, 50);
|
||||
let y = y.clamp(-50, 50);
|
||||
let xs = x.to_string();
|
||||
let ys = y.to_string();
|
||||
xdotool(&["mousemove_relative", "--", &xs, &ys]).await?;
|
||||
let _x = x.clamp(-50, 50);
|
||||
let _y = y.clamp(-50, 50);
|
||||
}
|
||||
InputCommand::Click { b } => {
|
||||
let b = b.clamp(1, 3);
|
||||
let bs = b.to_string();
|
||||
xdotool(&["click", &bs]).await?;
|
||||
let _b = b.clamp(1, 3);
|
||||
}
|
||||
InputCommand::Scroll { y } => {
|
||||
// xdotool: button 4 = scroll up, button 5 = scroll down
|
||||
let btn = if y < 0 { "4" } else { "5" };
|
||||
let count = y.unsigned_abs().clamp(1, 10).to_string();
|
||||
xdotool(&["click", "--repeat", &count, btn]).await?;
|
||||
let _y = y.clamp(-10, 10);
|
||||
}
|
||||
InputCommand::Ping => {
|
||||
return Ok(Some(r#"{"t":"p"}"#.to_string()));
|
||||
|
||||
Reference in New Issue
Block a user