show prompt responses in dialog
This commit is contained in:
@@ -58,6 +58,7 @@ async fn main() {
|
||||
.plugin(tauri_plugin_global_shortcut::Builder::new().build())
|
||||
.invoke_handler(tauri::generate_handler![toggle_popup, prompt_llm])
|
||||
.setup(|app| {
|
||||
/* Auto-hide popup when focus is lost
|
||||
if let Some(window) = app.get_webview_window("popup") {
|
||||
let w = window.clone();
|
||||
window.on_window_event(move |event| {
|
||||
@@ -68,6 +69,8 @@ async fn main() {
|
||||
}
|
||||
})
|
||||
}
|
||||
*/
|
||||
// Global shortcut to pull up the popup
|
||||
let shortcut = Shortcut::new(Some(Modifiers::META), Code::Space);
|
||||
app.global_shortcut()
|
||||
.on_shortcut(shortcut, move |app, _shortcut, event| {
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
"label": "popup",
|
||||
"title": "AI Quick Action",
|
||||
"url": "/popup",
|
||||
"width": 600,
|
||||
"height": 260,
|
||||
"width": 800,
|
||||
"height": 400,
|
||||
"decorations": false,
|
||||
"transparent": true,
|
||||
"alwaysOnTop": true,
|
||||
|
||||
@@ -3,12 +3,19 @@ use leptos::{ev::keydown, html::Input, prelude::*};
|
||||
use wasm_bindgen::{prelude::Closure, JsCast, JsValue};
|
||||
use wasm_bindgen_futures::spawn_local;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
struct Message {
|
||||
id: usize,
|
||||
text: String,
|
||||
is_user: bool,
|
||||
}
|
||||
|
||||
#[component]
|
||||
pub fn Popup() -> impl IntoView {
|
||||
// Prompt signals and and action
|
||||
let prompt_input_ref = NodeRef::<Input>::new();
|
||||
let (prompt_text, set_prompt_text) = signal(String::new());
|
||||
let (prompt_result, set_prompt_result) = signal(String::new());
|
||||
let (messages, set_messages) = signal(Vec::<Message>::new());
|
||||
// Action that calls the promp daemon
|
||||
let prompt_action = Action::new_local(|prompt: &String| {
|
||||
let prompt = prompt.clone();
|
||||
@@ -25,7 +32,13 @@ pub fn Popup() -> impl IntoView {
|
||||
// Update the model response div with the prompt result
|
||||
Effect::new(move |_| {
|
||||
if let Some(result) = prompt_action.value().get() {
|
||||
set_prompt_result.set(result)
|
||||
set_messages.update(|previous| {
|
||||
previous.push(Message {
|
||||
id: previous.len(),
|
||||
text: result,
|
||||
is_user: false,
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
// Clear the propt text-input when the window loses focus (and is hidden)
|
||||
@@ -64,15 +77,26 @@ pub fn Popup() -> impl IntoView {
|
||||
on:input=move |ev| set_prompt_text.set(event_target_value(&ev))
|
||||
on:keydown=move |ev| {
|
||||
if ev.key() == "Enter" {
|
||||
set_messages.update(|previous| {
|
||||
previous.push(Message {
|
||||
id: previous.len(),
|
||||
text: prompt_text.get(),
|
||||
is_user: true,
|
||||
});
|
||||
});
|
||||
prompt_action.dispatch(prompt_text.get());
|
||||
//set_prompt_result.update(|s| *s = prompt_action.value());
|
||||
set_prompt_text.update(|s| *s = "".to_string());
|
||||
}
|
||||
}
|
||||
prop:value=prompt_text
|
||||
/>
|
||||
<div class="response-area">
|
||||
<p>{move || prompt_result.get()}</p>
|
||||
<For each=move || messages.get()
|
||||
key=|msg| msg.id
|
||||
let(msg)
|
||||
>
|
||||
<div class=if msg.is_user {"msg msg-user"} else {"msg msg-model"}>{msg.text}</div>
|
||||
</For>
|
||||
</div>
|
||||
</main>
|
||||
}
|
||||
|
||||
@@ -21,3 +21,18 @@ body {
|
||||
background-color: #212121;
|
||||
border-radius: 15px;
|
||||
}
|
||||
|
||||
.response-area {
|
||||
width: 100%;
|
||||
height: 300px;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
.msg {
|
||||
margin: 1px;
|
||||
border: solid 1px #808080;
|
||||
}
|
||||
|
||||
.msg-user {
|
||||
text-align: end;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user