Overhaul UI

This commit is contained in:
Ethan 2024-12-27 13:38:08 -05:00
parent 809ab9a979
commit ba333b928e
4 changed files with 80 additions and 50 deletions

View File

@ -5,16 +5,16 @@ use crate::groq::GROQ_CLIENT;
pub struct ModelResponse { pub struct ModelResponse {
pub name: String, pub name: String,
pub message: String, pub message: String,
pub status: i32, pub tokens: i32,
pub time: f32, pub time: f32,
} }
impl ModelResponse { impl ModelResponse {
pub fn new(name: String, message: String, status: i32, time: f32) -> Self { pub fn new(name: String, message: String, tokens: i32, time: f32) -> Self {
Self { Self {
name, name,
message, message,
status, tokens,
time, time,
} }
} }
@ -22,13 +22,14 @@ impl ModelResponse {
pub async fn chat_completion(&mut self, prompt: String) { pub async fn chat_completion(&mut self, prompt: String) {
let response = GROQ_CLIENT.chat_completion(self.name.clone(), prompt).await; let response = GROQ_CLIENT.chat_completion(self.name.clone(), prompt).await;
self.message = response.choices[0].message.content.clone(); self.message = response.choices[0].message.content.clone();
self.status = 200; self.tokens = response.usage.total_tokens;
self.time = response.usage.total_time; self.time = response.usage.total_time;
} }
} }
impl Widget for &ModelResponse { impl Widget for &ModelResponse {
fn ui(self, ui: &mut Ui) -> Response { fn ui(self, ui: &mut Ui) -> Response {
ui.vertical(|ui| {
egui::Frame::none() egui::Frame::none()
.inner_margin(8.0) .inner_margin(8.0)
.rounding(4.0) .rounding(4.0)
@ -36,10 +37,10 @@ impl Widget for &ModelResponse {
.show(ui, |ui| { .show(ui, |ui| {
ui.label(RichText::new(&self.name).strong()); ui.label(RichText::new(&self.name).strong());
ui.horizontal_wrapped(|ui| {
ui.horizontal(|ui| { ui.horizontal(|ui| {
ui.horizontal(|ui| { ui.label("Tokens:");
ui.label("Status:"); ui.label(self.tokens.to_string());
ui.label(self.status.to_string());
}); });
ui.horizontal(|ui| { ui.horizontal(|ui| {
@ -53,9 +54,11 @@ impl Widget for &ModelResponse {
.rounding(4.0) .rounding(4.0)
.fill(egui::Color32::WHITE) .fill(egui::Color32::WHITE)
.show(ui, |ui| { .show(ui, |ui| {
ui.label(egui::RichText::new(&self.message).color(egui::Color32::BLACK)); ui.label(
egui::RichText::new(&self.message).color(egui::Color32::BLACK),
);
}); });
}) })
.response }).response
} }
} }

View File

@ -1,4 +1,4 @@
use eframe::egui::{self, Response, Ui, Widget}; use eframe::egui::{self, Response, RichText, Ui, Widget};
use super::{model_response::ModelResponse, state::AppState}; use super::{model_response::ModelResponse, state::AppState};
@ -33,23 +33,32 @@ impl<'a> Widget for ModelSelection<'a> {
self.app_state.selected_models.push(ModelResponse { self.app_state.selected_models.push(ModelResponse {
name: model.clone(), name: model.clone(),
message: "No message".to_string(), message: "No message".to_string(),
status: 0, tokens: 0,
time: 0.0, time: 0.0,
}); });
} }
} }
}); });
let selection_frame = egui::Frame::none()
.inner_margin(4.0)
.rounding(4.0)
.fill(egui::Color32::DARK_GRAY);
if self.app_state.selected_models.len() == 0 {
selection_frame.show(ui, |ui| {
ui.label(RichText::new("No models selected").strong());
});
return;
}
let mut model_to_remove: Option<String> = None; let mut model_to_remove: Option<String> = None;
for model in &self.app_state.selected_models { for model in &self.app_state.selected_models {
egui::Frame::none() selection_frame.show(ui, |ui| {
.inner_margin(8.0)
.rounding(4.0)
.fill(egui::Color32::WHITE)
.show(ui, |ui| {
ui.horizontal(|ui| { ui.horizontal(|ui| {
ui.label(model.name.clone()); ui.label(RichText::new(model.name.clone()).strong());
if ui.button("X").clicked() { if ui.button("X").clicked() {
model_to_remove.replace(model.name.clone()); model_to_remove.replace(model.name.clone());
} }

View File

@ -1,4 +1,4 @@
use eframe::egui::{Response, Ui, Widget}; use eframe::egui::{Response, TextEdit, Ui, Vec2, Widget};
use super::state::AppState; use super::state::AppState;
@ -15,7 +15,10 @@ impl<'a> PromptInput<'a> {
impl<'a> Widget for PromptInput<'a> { impl<'a> Widget for PromptInput<'a> {
fn ui(self, ui: &mut Ui) -> Response { fn ui(self, ui: &mut Ui) -> Response {
let label = ui.label("Prompt:"); let label = ui.label("Prompt:");
ui.text_edit_multiline(&mut self.app_state.prompt_input) ui.add_sized(
Vec2::new(ui.available_width(), 100.0),
TextEdit::multiline(&mut self.app_state.prompt_input),
)
.labelled_by(label.id); .labelled_by(label.id);
ui.horizontal(|ui| { ui.horizontal(|ui| {

View File

@ -1,4 +1,7 @@
use eframe::{egui, CreationContext}; use eframe::{
egui::{self, Layout, Separator},
CreationContext,
};
use super::{model_response::ModelResponse, model_selection, prompt_input}; use super::{model_response::ModelResponse, model_selection, prompt_input};
@ -38,11 +41,23 @@ impl eframe::App for AppState {
ui.add(prompt_input::PromptInput::new(self)); ui.add(prompt_input::PromptInput::new(self));
ui.horizontal(|ui| { ui.add(Separator::default().spacing(16.0));
let size = ui.available_size_before_wrap();
let widget_size = egui::Vec2 {
x: size.x / 4.0,
y: size.y,
};
ui.allocate_ui_with_layout(size, Layout::left_to_right(egui::Align::Min), |ui| {
egui::ScrollArea::both().show(ui, |ui| {
ui.horizontal_top(|ui| {
for model in &self.selected_models { for model in &self.selected_models {
ui.vertical(|ui| ui.add(model)); ui.add_sized(widget_size, model);
} }
}); });
}); });
});
});
} }
} }