feat: Enhance sound favorite management; add WebSocket event broadcasting for favoriting and unfavoriting sounds
This commit is contained in:
@@ -10,6 +10,7 @@ from app.repositories.favorite import FavoriteRepository
|
||||
from app.repositories.playlist import PlaylistRepository
|
||||
from app.repositories.sound import SoundRepository
|
||||
from app.repositories.user import UserRepository
|
||||
from app.services.socket import socket_manager
|
||||
|
||||
logger = get_logger(__name__)
|
||||
|
||||
@@ -55,6 +56,10 @@ class FavoriteService:
|
||||
if not sound:
|
||||
raise ValueError(f"Sound with ID {sound_id} not found")
|
||||
|
||||
# Get data for the event immediately after loading
|
||||
sound_name = sound.name
|
||||
user_name = user.name
|
||||
|
||||
# Check if already favorited
|
||||
existing = await favorite_repo.get_by_user_and_sound(user_id, sound_id)
|
||||
if existing:
|
||||
@@ -70,7 +75,28 @@ class FavoriteService:
|
||||
}
|
||||
favorite = await favorite_repo.create(favorite_data)
|
||||
logger.info("User %s favorited sound %s", user_id, sound_id)
|
||||
return favorite
|
||||
|
||||
# Get updated favorite count within the same session
|
||||
favorite_count = await favorite_repo.count_sound_favorites(sound_id)
|
||||
|
||||
# Emit sound_favorited event via WebSocket (outside the session)
|
||||
try:
|
||||
event_data = {
|
||||
"sound_id": sound_id,
|
||||
"sound_name": sound_name,
|
||||
"user_id": user_id,
|
||||
"user_name": user_name,
|
||||
"favorite_count": favorite_count,
|
||||
}
|
||||
await socket_manager.broadcast_to_all("sound_favorited", event_data)
|
||||
logger.info("Broadcasted sound_favorited event for sound %s", sound_id)
|
||||
except Exception:
|
||||
logger.exception(
|
||||
"Failed to broadcast sound_favorited event for sound %s",
|
||||
sound_id,
|
||||
)
|
||||
|
||||
return favorite
|
||||
|
||||
async def add_playlist_favorite(self, user_id: int, playlist_id: int) -> Favorite:
|
||||
"""Add a playlist to user's favorites.
|
||||
@@ -103,7 +129,8 @@ class FavoriteService:
|
||||
|
||||
# Check if already favorited
|
||||
existing = await favorite_repo.get_by_user_and_playlist(
|
||||
user_id, playlist_id,
|
||||
user_id,
|
||||
playlist_id,
|
||||
)
|
||||
if existing:
|
||||
raise ValueError(
|
||||
@@ -138,9 +165,41 @@ class FavoriteService:
|
||||
if not favorite:
|
||||
raise ValueError(f"Sound {sound_id} is not favorited by user {user_id}")
|
||||
|
||||
# Get user and sound info before deletion for the event
|
||||
user_repo = UserRepository(session)
|
||||
sound_repo = SoundRepository(session)
|
||||
user = await user_repo.get_by_id(user_id)
|
||||
sound = await sound_repo.get_by_id(sound_id)
|
||||
|
||||
# Get data for the event immediately after loading
|
||||
sound_name = sound.name if sound else "Unknown"
|
||||
user_name = user.name if user else "Unknown"
|
||||
|
||||
await favorite_repo.delete(favorite)
|
||||
logger.info("User %s removed sound %s from favorites", user_id, sound_id)
|
||||
|
||||
# Get updated favorite count after deletion within the same session
|
||||
favorite_count = await favorite_repo.count_sound_favorites(sound_id)
|
||||
|
||||
# Emit sound_favorited event via WebSocket (outside the session)
|
||||
try:
|
||||
event_data = {
|
||||
"sound_id": sound_id,
|
||||
"sound_name": sound_name,
|
||||
"user_id": user_id,
|
||||
"user_name": user_name,
|
||||
"favorite_count": favorite_count,
|
||||
}
|
||||
await socket_manager.broadcast_to_all("sound_favorited", event_data)
|
||||
logger.info(
|
||||
"Broadcasted sound_favorited event for sound %s removal", sound_id
|
||||
)
|
||||
except Exception:
|
||||
logger.exception(
|
||||
"Failed to broadcast sound_favorited event for sound %s removal",
|
||||
sound_id,
|
||||
)
|
||||
|
||||
async def remove_playlist_favorite(self, user_id: int, playlist_id: int) -> None:
|
||||
"""Remove a playlist from user's favorites.
|
||||
|
||||
@@ -156,7 +215,8 @@ class FavoriteService:
|
||||
favorite_repo = FavoriteRepository(session)
|
||||
|
||||
favorite = await favorite_repo.get_by_user_and_playlist(
|
||||
user_id, playlist_id,
|
||||
user_id,
|
||||
playlist_id,
|
||||
)
|
||||
if not favorite:
|
||||
raise ValueError(
|
||||
@@ -165,7 +225,9 @@ class FavoriteService:
|
||||
|
||||
await favorite_repo.delete(favorite)
|
||||
logger.info(
|
||||
"User %s removed playlist %s from favorites", user_id, playlist_id,
|
||||
"User %s removed playlist %s from favorites",
|
||||
user_id,
|
||||
playlist_id,
|
||||
)
|
||||
|
||||
async def get_user_favorites(
|
||||
@@ -230,7 +292,9 @@ class FavoriteService:
|
||||
async with self.db_session_factory() as session:
|
||||
favorite_repo = FavoriteRepository(session)
|
||||
return await favorite_repo.get_user_playlist_favorites(
|
||||
user_id, limit, offset,
|
||||
user_id,
|
||||
limit,
|
||||
offset,
|
||||
)
|
||||
|
||||
async def is_sound_favorited(self, user_id: int, sound_id: int) -> bool:
|
||||
|
||||
Reference in New Issue
Block a user