ausername-12345 commited on
Commit
987f439
Β·
1 Parent(s): fb8eda3

add conversation delete with confirm

Browse files

- DELETE /chat/conversations/{id} removes caller from ConversationMember
- βœ• button on each DM in sidebar calls deleteConversation()
- Clicking delete shows browser confirm dialog, then removes conversation
- If the deleted conversation is currently open, resets to empty state
- Clears msgCache for that conversation

Files changed (2) hide show
  1. src/chat.py +13 -0
  2. src/static/app.js +20 -0
src/chat.py CHANGED
@@ -81,6 +81,19 @@ def list_conversations(request: Request, db: Session = Depends(get_db)):
81
  result.sort(key=lambda x: x["last_message_at"] or "", reverse=True)
82
  return result
83
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
  # ─── Groups ───────────────────────────────────────────────────────────────────
85
 
86
  class CreateGroupRequest(BaseModel):
 
81
  result.sort(key=lambda x: x["last_message_at"] or "", reverse=True)
82
  return result
83
 
84
+ @router.delete("/conversations/{conversation_id}")
85
+ def delete_conversation(conversation_id: int, request: Request, db: Session = Depends(get_db)):
86
+ me = get_current_user_from_header(request, db)
87
+ membership = db.query(ConversationMember).filter(
88
+ ConversationMember.conversation_id == conversation_id,
89
+ ConversationMember.user_id == me.id
90
+ ).first()
91
+ if not membership:
92
+ raise HTTPException(status_code=404, detail="Conversation not found")
93
+ db.delete(membership)
94
+ db.commit()
95
+ return {"ok": True}
96
+
97
  # ─── Groups ───────────────────────────────────────────────────────────────────
98
 
99
  class CreateGroupRequest(BaseModel):
src/static/app.js CHANGED
@@ -743,6 +743,25 @@ function filterChats() {
743
  renderChatList();
744
  }
745
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
746
  function renderChatList() {
747
  const q = document.getElementById("sidebar-search").value.toLowerCase();
748
  const list = document.getElementById("chat-list");
@@ -765,6 +784,7 @@ function renderChatList() {
765
  <p class="text-xs text-gray-500 truncate">@${conv.other_user.username}</p>
766
  </div>
767
  ${conv.unread_count > 0 ? `<span class="w-5 h-5 rounded-full unread-badge text-white text-xs flex items-center justify-center font-medium">${conv.unread_count}</span>` : ""}
 
768
  `;
769
  list.appendChild(div);
770
  });
 
743
  renderChatList();
744
  }
745
 
746
+ async function deleteConversation(convId, event) {
747
+ if (event) { event.stopPropagation(); }
748
+ if (!confirm("Delete this conversation?")) return;
749
+ try {
750
+ await apiFetch(`/chat/conversations/${convId}`, token, "DELETE");
751
+ if (currentChat && currentChat.type === "dm" && currentChat.id === convId) {
752
+ currentChat = null;
753
+ document.getElementById("chat-window").classList.add("hidden");
754
+ document.getElementById("chat-window").classList.remove("flex");
755
+ document.getElementById("empty-state").classList.remove("hidden");
756
+ document.getElementById("call-btn").classList.add("hidden");
757
+ }
758
+ delete msgCache[convId];
759
+ await loadChats();
760
+ } catch (e) {
761
+ console.error("deleteConversation error:", e);
762
+ }
763
+ }
764
+
765
  function renderChatList() {
766
  const q = document.getElementById("sidebar-search").value.toLowerCase();
767
  const list = document.getElementById("chat-list");
 
784
  <p class="text-xs text-gray-500 truncate">@${conv.other_user.username}</p>
785
  </div>
786
  ${conv.unread_count > 0 ? `<span class="w-5 h-5 rounded-full unread-badge text-white text-xs flex items-center justify-center font-medium">${conv.unread_count}</span>` : ""}
787
+ <button onclick="deleteConversation(${conv.id}, event)" class="shrink-0 w-6 h-6 rounded-lg text-gray-600 hover:text-red-400 hover:bg-white/10 flex items-center justify-center text-xs transition-colors" title="Delete conversation">βœ•</button>
788
  `;
789
  list.appendChild(div);
790
  });