Add user ping system and room deletion functionality

Backend changes:
- Fix track deletion foreign key constraint (tracks.py)
  * Clear current_track_id from rooms before deleting track
  * Prevent deletion errors when track is currently playing

- Implement user ping/keepalive system (sync.py, websocket.py, ping_task.py, main.py)
  * Track last pong timestamp for each user
  * Background task sends ping every 30s, disconnects users after 60s timeout
  * Auto-pause playback when room becomes empty
  * Remove disconnected users from room_participants

- Enhance room deletion (rooms.py)
  * Broadcast room_deleted event to all connected users
  * Close all WebSocket connections before deletion
  * Cascade delete participants, queue, and messages

Frontend changes:
- Add ping/pong WebSocket handling (activeRoom.js)
  * Auto-respond to server pings
  * Handle room_deleted event with redirect to home

- Add room deletion UI (RoomView.vue, HomeView.vue, RoomCard.vue)
  * Delete button visible only to room owner
  * Confirmation dialog with warning
  * Delete button on room cards (shows on hover)
  * Redirect to home page after deletion

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-12-19 20:46:00 +03:00
parent ee8d79d155
commit 0fb16f791d
10 changed files with 398 additions and 9 deletions

View File

@@ -106,7 +106,25 @@ async def delete_room(
if room.owner_id != current_user.id:
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Not room owner")
# Уведомляем всех подключенных пользователей о удалении комнаты
await manager.broadcast_to_room(
room_id,
{"type": "room_deleted", "message": "Room has been deleted by owner"},
)
# Отключаем всех пользователей от WebSocket
if room_id in manager.active_connections:
connections = list(manager.active_connections[room_id])
for websocket, user_id in connections:
try:
await websocket.close(code=1000, reason="Room deleted")
except Exception:
pass
manager.disconnect(websocket, room_id, user_id)
# Удаляем комнату (cascade delete удалит participants, queue, messages)
await db.delete(room)
return {"status": "deleted"}