You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

164 lines
5.2 KiB

use std::sync::mpsc::Receiver;
use std::time::Duration;
use eframe::{
egui::{self, RichText, ScrollArea, Window},
emath::Align,
epaint::Color32,
};
use egui_toast::Toasts;
use serde::Deserialize;
use tungstenite::Message;
pub struct App {
rx: Receiver<Message>,
history: Vec<MessageLog>,
autoscroll: bool,
description: String,
selected_channel: String,
channels: Vec<String>,
description_shown: bool,
}
#[derive(Deserialize)]
struct MessageLog {
name: String,
description: String,
message: String,
channel: String,
}
#[derive(Deserialize)]
struct InteractionLog {
name: String,
command: String,
arguments: String,
channel: String,
}
#[derive(Deserialize)]
#[serde(tag = "type")]
enum Loggers {
InteractionLog(InteractionLog),
MessageLog(MessageLog),
}
impl App {
pub fn new(rx: Receiver<Message>) -> Self {
Self {
rx,
history: Vec::new(),
autoscroll: false,
description: "".to_string(),
selected_channel: "".to_string(),
channels: Vec::new(),
description_shown: false,
}
}
}
impl eframe::App for App {
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
let mut toasts = Toasts::new()
.anchor((10.0, 10.0))
.direction(egui::Direction::TopDown)
.align_to_end(false);
let message = self.rx.try_recv();
if let Ok(message) = message {
let text = message.to_string();
let json = serde_json::from_str(&text);
if let Ok(json) = json {
let json: Loggers = json;
match json {
Loggers::MessageLog(msg) => {
self.history.push(msg);
}
Loggers::InteractionLog(msg) => {
if self.selected_channel == msg.channel {
toasts.info(
format!(
"User {} called command /{} with arguments {}",
msg.name, msg.command, msg.arguments
),
Duration::from_secs(5),
);
}
}
}
} else if let Err(json) = json {
println!("{}", json);
}
}
egui::CentralPanel::default().show(ctx, |ui| {
Window::new("Description")
.open(&mut self.description_shown)
.collapsible(false)
.show(ctx, |ui| {
ScrollArea::vertical()
.id_source("description_box")
.show(ui, |ui| {
ui.label(&self.description);
});
});
ui.horizontal(|ui| {
ui.checkbox(&mut self.autoscroll, "Autoscroll");
if ui.button("Reset").clicked() {
self.history.clear();
self.channels.clear();
self.selected_channel.clear();
self.description.clear();
}
if ui.button("Description").clicked() {
self.description_shown = true;
}
});
ui.separator();
ui.horizontal(|ui| {
ScrollArea::horizontal()
.id_source("channel_bar")
.show(ui, |ui| {
for channel in &self.channels {
if ui.button(channel).clicked() {
self.selected_channel = channel.to_owned();
}
}
});
});
ui.separator();
ScrollArea::vertical()
.id_source("messages_list")
.show(ui, |ui| {
for msg in &self.history {
if !self.channels.contains(&msg.channel) {
self.channels.push((&msg.channel).to_owned());
}
if msg.channel == self.selected_channel {
ui.horizontal(|ui| {
ui.label(RichText::new(&msg.name).color(Color32::LIGHT_GRAY));
if !&msg.description.is_empty() {
self.description = (&msg.description).to_owned();
ui.label(RichText::new("[AI]").color(Color32::DARK_GRAY));
}
});
ui.label(&msg.message);
ui.separator();
}
if self.autoscroll {
ui.scroll_to_cursor(Some(Align::BOTTOM));
}
}
});
});
ctx.request_repaint();
toasts.show(ctx);
}
}