redvault-ai/darm_test/src/ui/mod.rs

88 lines
2.6 KiB
Rust

mod components;
use std::time::Duration;
use axum::{extract::State, response::IntoResponse};
use axum_controller::*;
use datastar::{
axum::ReadSignals,
prelude::{FragmentMergeMode, MergeFragments},
Sse,
};
use hypertext::{maud, GlobalAttributes, Renderable};
use serde::Deserialize;
use crate::{ui::components::*, AppState};
pub mod html_elements {
use hypertext::elements;
pub use hypertext::html_elements::*;
elements! {
bla {
blub
}
my_element {
my_attribute
}
}
}
#[derive(Deserialize, Debug)]
struct Signals {
msginput: String,
}
pub struct UiController {}
#[controller(
state = AppState
)]
impl UiController {
#[route(GET "/msg")]
#[tracing::instrument]
async fn message(
State(_): State<AppState>,
ReadSignals(signals): ReadSignals<Signals>,
) -> impl IntoResponse {
tokio::time::sleep(Duration::from_millis(250)).await;
Sse(async_stream::stream! {
yield MergeFragments::new(maud! { div #user-1 class="mb-2 animated animated-bounce" { strong { "You:" } (signals.msginput) } }.render())
.selector("#chat")
.merge_mode(FragmentMergeMode::Append)
.into();
tokio::time::sleep(Duration::from_millis(250)).await;
yield MergeFragments::new(maud! { div #llm-1 class="mb-2 animated animated-bounce" { strong { "LLM:" } "This is a mock response."} }.render())
.selector("#chat")
.merge_mode(FragmentMergeMode::Append)
.into();
})
}
#[route(GET "/")]
#[tracing::instrument]
async fn index(State(_): State<AppState>) -> impl IntoResponse {
main_page(maud! {
div .container .p-4 .mx-auto {
h1 .m-4 .text-2xl .font-bold {
"LLM Chat App"
}
div .p-6 .bg-white .rounded-lg .shadow-md {
div #chat .m-4 {
// Chat messages will appear here
}
form id="chat-form" {
textarea #user-input .p-2 .m-2 .w-full .rounded-lg .border data-bind-msginput placeholder="Type your message..." {}
button #send-btn class="btn" type="button" data-on-click="@get('/msg')" {
"Send"
}
}
}
}
}
)
.render()
}
}