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

@@ -9,6 +9,7 @@ from .routers import auth, rooms, tracks, websocket, messages
from .database import async_session
from .models.room import Room
from .services.sync import manager
from .services.ping_task import ping_users_task
from .config import get_settings
# Setup logging
@@ -62,15 +63,22 @@ async def periodic_sync():
@asynccontextmanager
async def lifespan(app: FastAPI):
# Start background sync task
# Start background tasks
sync_task = asyncio.create_task(periodic_sync())
ping_task = asyncio.create_task(ping_users_task())
logger.info("Background tasks started: periodic_sync, ping_users_task")
yield
# Cleanup
sync_task.cancel()
ping_task.cancel()
try:
await sync_task
except asyncio.CancelledError:
pass
try:
await ping_task
except asyncio.CancelledError:
pass
app = FastAPI(title="EnigFM", description="Listen to music together with friends", lifespan=lifespan)