initial
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
/target
|
||||||
3754
Cargo.lock
generated
Normal file
3754
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
8
Cargo.toml
Normal file
8
Cargo.toml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
[package]
|
||||||
|
name = "sm-admingate"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
eframe = "0.32.0"
|
||||||
|
egui = "0.32.0"
|
||||||
BIN
DejaVuSans.ttf
Normal file
BIN
DejaVuSans.ttf
Normal file
Binary file not shown.
186
src/main.rs
Normal file
186
src/main.rs
Normal file
@@ -0,0 +1,186 @@
|
|||||||
|
use eframe::egui;
|
||||||
|
use egui::{Key, RichText};
|
||||||
|
use std::collections::VecDeque;
|
||||||
|
use egui::{FontData, FontDefinitions, FontFamily};
|
||||||
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
|
const MAX_KEYS: usize = 6;
|
||||||
|
const SECRET_COMBO: [Key; MAX_KEYS] = [
|
||||||
|
Key::ArrowUp,
|
||||||
|
Key::ArrowUp,
|
||||||
|
Key::ArrowDown,
|
||||||
|
Key::ArrowDown,
|
||||||
|
Key::ArrowLeft,
|
||||||
|
Key::ArrowRight,
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
struct AdminGateApp {
|
||||||
|
key_history: VecDeque<Key>,
|
||||||
|
should_run_admin_command: Arc<Mutex<bool>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for AdminGateApp {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
key_history: VecDeque::with_capacity(MAX_KEYS),
|
||||||
|
should_run_admin_command: Arc::new(Mutex::new(false)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl eframe::App for AdminGateApp {
|
||||||
|
fn update(&mut self, ctx: &egui::Context, _: &mut eframe::Frame) {
|
||||||
|
egui::CentralPanel::default().show(ctx, |ui| {
|
||||||
|
ui.vertical_centered(|ui| {
|
||||||
|
ui.heading("Admin Settings Gate");
|
||||||
|
|
||||||
|
ui.add_space(20.0);
|
||||||
|
|
||||||
|
// Display last 6 keys
|
||||||
|
let key_display = self
|
||||||
|
.key_history
|
||||||
|
.iter()
|
||||||
|
.map(|k| match k {
|
||||||
|
Key::ArrowUp => "↑",
|
||||||
|
Key::ArrowDown => "↓",
|
||||||
|
Key::ArrowLeft => "←",
|
||||||
|
Key::ArrowRight => "→",
|
||||||
|
_ => "?",
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join(" ");
|
||||||
|
|
||||||
|
ui.label(
|
||||||
|
RichText::new(&key_display)
|
||||||
|
.size(60.0)
|
||||||
|
.strong(),
|
||||||
|
);
|
||||||
|
|
||||||
|
ui.add_space(20.0);
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
egui::TopBottomPanel::bottom("footer").show(ctx, |ui| {
|
||||||
|
ui.horizontal_centered(|ui| {
|
||||||
|
ui.label(egui::RichText::new("Press ESC to quit. Enter runs the admin command.").size(24.0).weak());
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Input handling
|
||||||
|
for event in &ctx.input(|i| i.raw.events.clone()) {
|
||||||
|
if let egui::Event::Key {
|
||||||
|
key,
|
||||||
|
pressed: true,
|
||||||
|
modifiers: _,
|
||||||
|
physical_key : _,
|
||||||
|
repeat: _,
|
||||||
|
} = event
|
||||||
|
{
|
||||||
|
match key {
|
||||||
|
Key::ArrowUp | Key::ArrowDown | Key::ArrowLeft | Key::ArrowRight => {
|
||||||
|
if self.key_history.len() == MAX_KEYS {
|
||||||
|
self.key_history.pop_front();
|
||||||
|
}
|
||||||
|
self.key_history.push_back(*key);
|
||||||
|
//self.should_run_admin_command = false; // reset status
|
||||||
|
}
|
||||||
|
Key::Enter => {
|
||||||
|
if self.key_history.len() == MAX_KEYS
|
||||||
|
&& self
|
||||||
|
.key_history
|
||||||
|
.iter()
|
||||||
|
.copied()
|
||||||
|
.eq(SECRET_COMBO.iter().copied())
|
||||||
|
{
|
||||||
|
// Run admin command
|
||||||
|
*self.should_run_admin_command.lock().unwrap() = true;
|
||||||
|
ctx.send_viewport_cmd(egui::ViewportCommand::Close); // This shuts down the GUI cleanly
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Key::Escape => {
|
||||||
|
std::process::exit(0);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.request_repaint(); // keep UI responsive
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn setup_custom_fonts(ctx: &egui::Context) {
|
||||||
|
let mut fonts = FontDefinitions::default();
|
||||||
|
|
||||||
|
// Add your custom font
|
||||||
|
fonts.font_data.insert(
|
||||||
|
"custom".to_string(),
|
||||||
|
FontData::from_owned(
|
||||||
|
std::fs::read("DejaVuSans.ttf").expect("Failed to load font"),
|
||||||
|
).into(),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Use the custom font for all proportional and monospace text
|
||||||
|
fonts
|
||||||
|
.families
|
||||||
|
.get_mut(&FontFamily::Proportional)
|
||||||
|
.unwrap()
|
||||||
|
.insert(0, "custom".to_string());
|
||||||
|
|
||||||
|
fonts
|
||||||
|
.families
|
||||||
|
.get_mut(&FontFamily::Monospace)
|
||||||
|
.unwrap()
|
||||||
|
.insert(0, "custom".to_string());
|
||||||
|
|
||||||
|
ctx.set_fonts(fonts);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
fn main() -> eframe::Result<()> {
|
||||||
|
|
||||||
|
let should_run_admin_command = Arc::new(Mutex::new(false));
|
||||||
|
let shared_flag = should_run_admin_command.clone();
|
||||||
|
|
||||||
|
let app = AdminGateApp {
|
||||||
|
key_history: VecDeque::with_capacity(6),
|
||||||
|
should_run_admin_command: shared_flag,
|
||||||
|
};
|
||||||
|
|
||||||
|
let options = eframe::NativeOptions::default();
|
||||||
|
let result = eframe::run_native(
|
||||||
|
"Admin Gate",
|
||||||
|
options,
|
||||||
|
Box::new(|cc| {
|
||||||
|
// Setup fonts
|
||||||
|
setup_custom_fonts(&cc.egui_ctx);
|
||||||
|
Ok(Box::new(app))
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// After GUI closes
|
||||||
|
if *should_run_admin_command.lock().unwrap() {
|
||||||
|
println!("✅ Running admin command...");
|
||||||
|
|
||||||
|
match std::process::Command::new("sh")
|
||||||
|
.arg("-c")
|
||||||
|
.arg("kitty")
|
||||||
|
.status() // ← wait until it finishes
|
||||||
|
{
|
||||||
|
Ok(status) => {
|
||||||
|
println!("Admin command exited with: {}", status);
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!("❌ Failed to run admin command: {}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user