mirror of
https://github.com/perstarkse/minne.git
synced 2026-05-25 17:09:58 +02:00
feat: chat conversation list titles, sorting, etc
This commit is contained in:
@@ -224,3 +224,110 @@ pub async fn new_chat_user_message(
|
||||
|
||||
Ok(response.into_response())
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct PatchConversationTitle {
|
||||
title: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct DrawerContext {
|
||||
user: User,
|
||||
conversation_archive: Vec<Conversation>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
edit_conversation_id: Option<String>,
|
||||
}
|
||||
pub async fn show_conversation_editing_title(
|
||||
State(state): State<HtmlState>,
|
||||
RequireUser(user): RequireUser,
|
||||
Path(conversation_id): Path<String>,
|
||||
) -> Result<impl IntoResponse, HtmlError> {
|
||||
let conversation_archive = User::get_user_conversations(&user.id, &state.db).await?;
|
||||
|
||||
let owns = conversation_archive
|
||||
.iter()
|
||||
.any(|c| c.id == conversation_id && c.user_id == user.id);
|
||||
if !owns {
|
||||
return Ok(TemplateResponse::unauthorized().into_response());
|
||||
}
|
||||
|
||||
Ok(TemplateResponse::new_template(
|
||||
"chat/drawer.html",
|
||||
DrawerContext {
|
||||
user,
|
||||
conversation_archive,
|
||||
edit_conversation_id: Some(conversation_id),
|
||||
},
|
||||
)
|
||||
.into_response())
|
||||
}
|
||||
|
||||
pub async fn patch_conversation_title(
|
||||
State(state): State<HtmlState>,
|
||||
RequireUser(user): RequireUser,
|
||||
Path(conversation_id): Path<String>,
|
||||
Form(form): Form<PatchConversationTitle>,
|
||||
) -> Result<impl IntoResponse, HtmlError> {
|
||||
Conversation::patch_title(&conversation_id, &user.id, &form.title, &state.db).await?;
|
||||
|
||||
let updated_conversations = User::get_user_conversations(&user.id, &state.db).await?;
|
||||
|
||||
Ok(TemplateResponse::new_template(
|
||||
"chat/drawer.html",
|
||||
DrawerContext {
|
||||
user,
|
||||
conversation_archive: updated_conversations,
|
||||
edit_conversation_id: None,
|
||||
},
|
||||
)
|
||||
.into_response())
|
||||
}
|
||||
|
||||
pub async fn delete_conversation(
|
||||
State(state): State<HtmlState>,
|
||||
RequireUser(user): RequireUser,
|
||||
Path(conversation_id): Path<String>,
|
||||
) -> Result<impl IntoResponse, HtmlError> {
|
||||
let conversation: Conversation = state
|
||||
.db
|
||||
.get_item(&conversation_id)
|
||||
.await?
|
||||
.ok_or_else(|| AppError::NotFound("Conversation not found".to_string()))?;
|
||||
|
||||
if conversation.user_id != user.id {
|
||||
return Ok(TemplateResponse::unauthorized().into_response());
|
||||
}
|
||||
|
||||
state
|
||||
.db
|
||||
.delete_item::<Conversation>(&conversation_id)
|
||||
.await?;
|
||||
|
||||
let conversation_archive = User::get_user_conversations(&user.id, &state.db).await?;
|
||||
|
||||
Ok(TemplateResponse::new_template(
|
||||
"chat/drawer.html",
|
||||
DrawerContext {
|
||||
user,
|
||||
conversation_archive,
|
||||
edit_conversation_id: None,
|
||||
},
|
||||
)
|
||||
.into_response())
|
||||
}
|
||||
pub async fn reload_sidebar(
|
||||
State(state): State<HtmlState>,
|
||||
RequireUser(user): RequireUser,
|
||||
) -> Result<impl IntoResponse, HtmlError> {
|
||||
let conversation_archive = User::get_user_conversations(&user.id, &state.db).await?;
|
||||
|
||||
Ok(TemplateResponse::new_template(
|
||||
"chat/drawer.html",
|
||||
DrawerContext {
|
||||
user,
|
||||
conversation_archive,
|
||||
edit_conversation_id: None,
|
||||
},
|
||||
)
|
||||
.into_response())
|
||||
}
|
||||
|
||||
@@ -8,7 +8,8 @@ use axum::{
|
||||
Router,
|
||||
};
|
||||
use chat_handlers::{
|
||||
new_chat_user_message, new_user_message, show_chat_base, show_existing_chat,
|
||||
delete_conversation, new_chat_user_message, new_user_message, patch_conversation_title,
|
||||
reload_sidebar, show_chat_base, show_conversation_editing_title, show_existing_chat,
|
||||
show_initialized_chat,
|
||||
};
|
||||
use message_response_stream::get_response_stream;
|
||||
@@ -23,7 +24,17 @@ where
|
||||
{
|
||||
Router::new()
|
||||
.route("/chat", get(show_chat_base).post(new_chat_user_message))
|
||||
.route("/chat/:id", get(show_existing_chat).post(new_user_message))
|
||||
.route(
|
||||
"/chat/:id",
|
||||
get(show_existing_chat)
|
||||
.post(new_user_message)
|
||||
.delete(delete_conversation),
|
||||
)
|
||||
.route(
|
||||
"/chat/:id/title",
|
||||
get(show_conversation_editing_title).patch(patch_conversation_title),
|
||||
)
|
||||
.route("/chat/sidebar", get(reload_sidebar))
|
||||
.route("/initialized-chat", post(show_initialized_chat))
|
||||
.route("/chat/response-stream", get(get_response_stream))
|
||||
.route("/chat/reference/:id", get(show_reference_tooltip))
|
||||
|
||||
Reference in New Issue
Block a user