delete messages + fix layout overflow
- DELETE /api/channels/{id}/messages/{msg_id} — soft delete, own only
- Broadcasts WsEvent::Delete to subscribers
- UI: "Del" button on hover for own messages (turns red)
- Fix layout: h-full + overflow-hidden on flex containers
- ScrollArea gets min-h-0 to properly constrain in flex
- Messages no longer push compose past viewport
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -49,6 +49,10 @@ async fn main() {
|
||||
"/api/channels/{channel_id}/messages",
|
||||
get(routes::list_messages).post(routes::post_message),
|
||||
)
|
||||
.route(
|
||||
"/api/channels/{channel_id}/messages/{msg_id}",
|
||||
axum::routing::delete(routes::delete_message),
|
||||
)
|
||||
.route("/ws/{channel_id}", get(ws::ws_handler))
|
||||
.fallback_service(
|
||||
ServeDir::new("static").fallback(ServeFile::new("static/index.html")),
|
||||
|
||||
@@ -278,6 +278,47 @@ pub async fn post_message(
|
||||
Ok((StatusCode::CREATED, Json(message)))
|
||||
}
|
||||
|
||||
pub async fn delete_message(
|
||||
State(state): State<AppState>,
|
||||
Path((channel_id, msg_id)): Path<(String, String)>,
|
||||
Query(user_param): Query<UserParam>,
|
||||
) -> Result<impl IntoResponse> {
|
||||
let user_id = resolve_user(&state.db, &user_param).await?;
|
||||
|
||||
// Verify message exists and belongs to this user
|
||||
let row = sqlx::query_as::<_, MessageWithUserRow>(
|
||||
"SELECT m.*, u.id as u_id, u.username, u.display_name, u.role, u.created_at as u_created_at \
|
||||
FROM messages m JOIN users u ON m.user_id = u.id WHERE m.id = ? AND m.channel_id = ?",
|
||||
)
|
||||
.bind(&msg_id)
|
||||
.bind(&channel_id)
|
||||
.fetch_optional(&state.db)
|
||||
.await?;
|
||||
|
||||
let row = match row {
|
||||
Some(r) => r,
|
||||
None => return Err(AppError::NotFound("Message not found".into())),
|
||||
};
|
||||
|
||||
if row.user_id != user_id {
|
||||
return Err(AppError::BadRequest("Can only delete your own messages".into()));
|
||||
}
|
||||
|
||||
// Soft delete
|
||||
sqlx::query("UPDATE messages SET deleted_at = strftime('%Y-%m-%dT%H:%M:%SZ', 'now') WHERE id = ?")
|
||||
.bind(&msg_id)
|
||||
.execute(&state.db)
|
||||
.await?;
|
||||
|
||||
// Broadcast delete event
|
||||
let tx = state.get_sender(&channel_id).await;
|
||||
let _ = tx.send(WsEvent::Delete {
|
||||
id: uuid::Uuid::parse_str(&msg_id).unwrap(),
|
||||
});
|
||||
|
||||
Ok(StatusCode::NO_CONTENT)
|
||||
}
|
||||
|
||||
// ── Joined row type for message + user ──
|
||||
|
||||
#[derive(Debug, sqlx::FromRow)]
|
||||
|
||||
Reference in New Issue
Block a user