feat: enhance MusicPlayer and SocketProvider with playlist management and real-time updates
This commit is contained in:
@@ -47,7 +47,8 @@ export function MusicPlayer() {
|
||||
|
||||
const progressBarRef = useRef<HTMLDivElement>(null)
|
||||
|
||||
if (!currentTrack) {
|
||||
// Show player if there's a playlist, even if no current track is playing
|
||||
if (playlist.length === 0) {
|
||||
return null
|
||||
}
|
||||
|
||||
@@ -98,7 +99,7 @@ export function MusicPlayer() {
|
||||
return (
|
||||
<Card className="fixed bottom-4 right-4 w-80 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60 border shadow-lg z-50">
|
||||
{/* Thumbnail */}
|
||||
{currentTrack.thumbnail && (
|
||||
{currentTrack?.thumbnail && (
|
||||
<div className="relative h-32 w-full overflow-hidden rounded-t-lg">
|
||||
<img
|
||||
src={currentTrack.thumbnail}
|
||||
@@ -122,9 +123,9 @@ export function MusicPlayer() {
|
||||
{/* Track info */}
|
||||
<div className="space-y-1">
|
||||
<h3 className="font-medium text-sm leading-tight line-clamp-1">
|
||||
{currentTrack.title}
|
||||
{currentTrack?.title || 'No track selected'}
|
||||
</h3>
|
||||
{currentTrack.artist && (
|
||||
{currentTrack?.artist && (
|
||||
<p className="text-xs text-muted-foreground line-clamp-1">
|
||||
{currentTrack.artist}
|
||||
</p>
|
||||
@@ -262,7 +263,7 @@ export function MusicPlayer() {
|
||||
{/* Main player area */}
|
||||
<div className="flex-1 flex flex-col items-center justify-center p-8">
|
||||
{/* Large thumbnail */}
|
||||
{currentTrack.thumbnail && (
|
||||
{currentTrack?.thumbnail && (
|
||||
<div className="w-80 h-80 rounded-lg overflow-hidden mb-6 shadow-lg">
|
||||
<img
|
||||
src={currentTrack.thumbnail}
|
||||
@@ -274,8 +275,8 @@ export function MusicPlayer() {
|
||||
|
||||
{/* Track info */}
|
||||
<div className="text-center mb-6">
|
||||
<h1 className="text-2xl font-bold mb-2">{currentTrack.title}</h1>
|
||||
{currentTrack.artist && (
|
||||
<h1 className="text-2xl font-bold mb-2">{currentTrack?.title || 'No track selected'}</h1>
|
||||
{currentTrack?.artist && (
|
||||
<p className="text-lg text-muted-foreground">{currentTrack.artist}</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -21,6 +21,7 @@ export function NavPlan({ user }: NavPlanProps) {
|
||||
if (!socket || !isConnected) return
|
||||
|
||||
const handleCreditsChanged = (data: { credits: number }) => {
|
||||
console.log('WAAAAAAZAAAA')
|
||||
setCredits(data.credits)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import { createContext, useContext, useState, useRef, useEffect, type ReactNode } from 'react'
|
||||
import { useSocket } from './SocketContext'
|
||||
import { apiService } from '@/services/api'
|
||||
|
||||
export interface Track {
|
||||
id: string
|
||||
@@ -41,6 +43,7 @@ interface MusicPlayerContextType {
|
||||
nextTrack: () => void
|
||||
previousTrack: () => void
|
||||
playTrack: (trackIndex: number) => void
|
||||
loadPlaylist: (playlistId: number) => void
|
||||
addToPlaylist: (track: Track) => void
|
||||
removeFromPlaylist: (trackId: string) => void
|
||||
clearPlaylist: () => void
|
||||
@@ -63,232 +66,233 @@ interface MusicPlayerProviderProps {
|
||||
}
|
||||
|
||||
export function MusicPlayerProvider({ children }: MusicPlayerProviderProps) {
|
||||
const audioRef = useRef<HTMLAudioElement | null>(null)
|
||||
const { socket } = useSocket()
|
||||
|
||||
// Playback state
|
||||
const [isPlaying, setIsPlaying] = useState(false)
|
||||
const [currentTime, setCurrentTime] = useState(0)
|
||||
const [duration, setDuration] = useState(0)
|
||||
const [volume, setVolumeState] = useState(0.8)
|
||||
const [volume, setVolumeState] = useState(80)
|
||||
const [isMuted, setIsMuted] = useState(false)
|
||||
const [playMode, setPlayMode] = useState<PlayMode>('continuous')
|
||||
const [playMode, setPlayModeState] = useState<PlayMode>('continuous')
|
||||
|
||||
// Playlist state
|
||||
const [currentTrackIndex, setCurrentTrackIndex] = useState(0)
|
||||
const [playlist, setPlaylist] = useState<Track[]>([
|
||||
{
|
||||
id: '1',
|
||||
title: 'Cheryl Lynn - Got To Be Real',
|
||||
artist: 'Cheryl Lynn',
|
||||
duration: 240,
|
||||
thumbnail: '/api/sounds/stream/thumbnails/Cheryl Lynn - Got To Be Real Official Audio_fI569nw0YUQ.webp',
|
||||
url: '/api/sounds/stream/Cheryl Lynn - Got To Be Real Official Audio_fI569nw0YUQ.opus'
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
title: 'The Whispers - And The Beat Goes On',
|
||||
artist: 'The Whispers',
|
||||
duration: 280,
|
||||
thumbnail: '/api/sounds/stream/thumbnails/The Whispers - And The Beat Goes On Official Video_pEmX5HR9ZxU.jpg',
|
||||
url: '/api/sounds/stream/The Whispers - And The Beat Goes On Official Video_pEmX5HR9ZxU.opus'
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
title: 'OLD RAP VS NEW RAP',
|
||||
artist: 'Mister V, Jhon Rachid, Maskey',
|
||||
duration: 320,
|
||||
thumbnail: '/api/sounds/stream/thumbnails/OLD RAP VS NEW RAP Ft Mister V Jhon Rachid Maskey _PAFYcOFE3DY.webp',
|
||||
url: '/api/sounds/stream/OLD RAP VS NEW RAP Ft Mister V Jhon Rachid Maskey _PAFYcOFE3DY.opus'
|
||||
}
|
||||
])
|
||||
const [playlist, setPlaylist] = useState<Track[]>([])
|
||||
const [currentPlaylistId, setCurrentPlaylistId] = useState<number | null>(null)
|
||||
const [currentTrack, setCurrentTrack] = useState<Track | null>(null)
|
||||
|
||||
// UI state
|
||||
const [isMinimized, setIsMinimized] = useState(true)
|
||||
const [showPlaylist, setShowPlaylist] = useState(false)
|
||||
|
||||
const currentTrack = playlist[currentTrackIndex] || null
|
||||
|
||||
// Initialize audio element
|
||||
// Fetch initial player state on mount
|
||||
useEffect(() => {
|
||||
audioRef.current = new Audio()
|
||||
const fetchInitialState = async () => {
|
||||
try {
|
||||
console.log('🎵 MusicPlayerContext: Fetching initial player state...')
|
||||
const response = await apiService.get('/api/player/state')
|
||||
const state = await response.json()
|
||||
|
||||
const audio = audioRef.current
|
||||
console.log('🎵 MusicPlayerContext: Initial state received', {
|
||||
playlist_id: state.playlist_id,
|
||||
is_playing: state.is_playing,
|
||||
current_time: state.current_time,
|
||||
duration: state.duration,
|
||||
playlist_length: state.playlist?.length
|
||||
})
|
||||
|
||||
const handleTimeUpdate = () => {
|
||||
setCurrentTime(audio.currentTime)
|
||||
// If no playlist is loaded, try to load the main playlist
|
||||
if (!state.playlist_id) {
|
||||
console.log('🎵 MusicPlayerContext: No playlist loaded, attempting to load main playlist...')
|
||||
try {
|
||||
await apiService.post('/api/player/load-main-playlist')
|
||||
// Fetch state again after loading main playlist
|
||||
const newResponse = await apiService.get('/api/player/state')
|
||||
const newState = await newResponse.json()
|
||||
console.log('🎵 MusicPlayerContext: Main playlist loaded, new state:', {
|
||||
playlist_id: newState.playlist_id,
|
||||
playlist_length: newState.playlist?.length
|
||||
})
|
||||
state = newState
|
||||
} catch (loadError) {
|
||||
console.warn('🎵 MusicPlayerContext: Failed to load main playlist:', loadError)
|
||||
}
|
||||
}
|
||||
|
||||
const handleLoadedMetadata = () => {
|
||||
setDuration(audio.duration)
|
||||
// Update all state from backend
|
||||
console.log('🎵 MusicPlayerContext: Updating initial state in React')
|
||||
setIsPlaying(state.is_playing || false)
|
||||
setCurrentTime(state.current_time || 0)
|
||||
setDuration(state.duration || 0)
|
||||
setVolumeState(state.volume || 80)
|
||||
setIsMuted(state.volume === 0)
|
||||
setPlayModeState(state.play_mode || 'continuous')
|
||||
setCurrentTrackIndex(state.current_track_index || 0)
|
||||
setPlaylist(state.playlist || [])
|
||||
setCurrentPlaylistId(state.playlist_id || null)
|
||||
setCurrentTrack(state.current_track || null)
|
||||
|
||||
console.log('🎵 MusicPlayerContext: Initial state setup complete')
|
||||
} catch (error) {
|
||||
console.error('❌ MusicPlayerContext: Failed to fetch initial player state:', error)
|
||||
}
|
||||
}
|
||||
|
||||
const handleEnded = () => {
|
||||
handleTrackEnd()
|
||||
}
|
||||
|
||||
audio.addEventListener('timeupdate', handleTimeUpdate)
|
||||
audio.addEventListener('loadedmetadata', handleLoadedMetadata)
|
||||
audio.addEventListener('ended', handleEnded)
|
||||
|
||||
return () => {
|
||||
audio.removeEventListener('timeupdate', handleTimeUpdate)
|
||||
audio.removeEventListener('loadedmetadata', handleLoadedMetadata)
|
||||
audio.removeEventListener('ended', handleEnded)
|
||||
audio.pause()
|
||||
}
|
||||
fetchInitialState()
|
||||
}, [])
|
||||
|
||||
// Update audio source when track changes
|
||||
// Listen for real-time player updates via SocketIO
|
||||
useEffect(() => {
|
||||
if (audioRef.current && currentTrack) {
|
||||
audioRef.current.src = currentTrack.url
|
||||
audioRef.current.load()
|
||||
}
|
||||
}, [currentTrack])
|
||||
console.log('🎵 MusicPlayerContext: Setting up SocketIO listeners', { hasSocket: !!socket });
|
||||
|
||||
// Update audio volume and mute state
|
||||
useEffect(() => {
|
||||
if (audioRef.current) {
|
||||
audioRef.current.volume = isMuted ? 0 : volume
|
||||
if (!socket) {
|
||||
console.log('⏳ MusicPlayerContext: No socket available yet');
|
||||
return;
|
||||
}
|
||||
}, [volume, isMuted])
|
||||
|
||||
const handleTrackEnd = () => {
|
||||
switch (playMode) {
|
||||
case 'loop-one':
|
||||
if (audioRef.current) {
|
||||
audioRef.current.currentTime = 0
|
||||
audioRef.current.play()
|
||||
const handlePlayerStateUpdate = (state: any) => {
|
||||
console.log('🎵 MusicPlayerContext: Received player state update', {
|
||||
is_playing: state.is_playing,
|
||||
current_time: state.current_time,
|
||||
duration: state.duration,
|
||||
volume: state.volume,
|
||||
current_track: state.current_track?.title,
|
||||
playlist_length: state.playlist?.length
|
||||
});
|
||||
|
||||
setIsPlaying(state.is_playing || false)
|
||||
setCurrentTime(state.current_time || 0)
|
||||
setDuration(state.duration || 0)
|
||||
setVolumeState(state.volume || 80)
|
||||
setIsMuted(state.volume === 0)
|
||||
setPlayModeState(state.play_mode || 'continuous')
|
||||
setCurrentTrackIndex(state.current_track_index || 0)
|
||||
setPlaylist(state.playlist || [])
|
||||
setCurrentPlaylistId(state.playlist_id || null)
|
||||
setCurrentTrack(state.current_track || null)
|
||||
}
|
||||
break
|
||||
case 'loop-playlist':
|
||||
nextTrack()
|
||||
break
|
||||
case 'random':
|
||||
playRandomTrack()
|
||||
break
|
||||
case 'continuous':
|
||||
if (currentTrackIndex < playlist.length - 1) {
|
||||
nextTrack()
|
||||
|
||||
console.log('🎵 MusicPlayerContext: Registering player_state_update listener');
|
||||
socket.on('player_state_update', handlePlayerStateUpdate)
|
||||
|
||||
return () => {
|
||||
console.log('🎵 MusicPlayerContext: Cleaning up SocketIO listeners');
|
||||
socket.off('player_state_update', handlePlayerStateUpdate)
|
||||
}
|
||||
}, [socket])
|
||||
|
||||
const play = async () => {
|
||||
try {
|
||||
await apiService.post('/api/player/play')
|
||||
} catch (error) {
|
||||
console.error('Failed to play:', error)
|
||||
}
|
||||
}
|
||||
|
||||
const pause = async () => {
|
||||
try {
|
||||
await apiService.post('/api/player/pause')
|
||||
} catch (error) {
|
||||
console.error('Failed to pause:', error)
|
||||
}
|
||||
}
|
||||
|
||||
const stop = async () => {
|
||||
try {
|
||||
await apiService.post('/api/player/stop')
|
||||
} catch (error) {
|
||||
console.error('Failed to stop:', error)
|
||||
}
|
||||
}
|
||||
|
||||
const togglePlayPause = async () => {
|
||||
if (isPlaying) {
|
||||
await pause()
|
||||
} else {
|
||||
stop()
|
||||
}
|
||||
break
|
||||
await play()
|
||||
}
|
||||
}
|
||||
|
||||
const play = () => {
|
||||
if (audioRef.current && currentTrack) {
|
||||
audioRef.current.play()
|
||||
setIsPlaying(true)
|
||||
const seekTo = async (time: number) => {
|
||||
try {
|
||||
const position = duration > 0 ? time / duration : 0
|
||||
await apiService.post('/api/player/seek', { position })
|
||||
} catch (error) {
|
||||
console.error('Failed to seek:', error)
|
||||
}
|
||||
}
|
||||
|
||||
const pause = () => {
|
||||
if (audioRef.current) {
|
||||
audioRef.current.pause()
|
||||
setIsPlaying(false)
|
||||
const setVolume = async (newVolume: number) => {
|
||||
try {
|
||||
await apiService.post('/api/player/volume', { volume: newVolume })
|
||||
} catch (error) {
|
||||
console.error('Failed to set volume:', error)
|
||||
}
|
||||
}
|
||||
|
||||
const stop = () => {
|
||||
if (audioRef.current) {
|
||||
audioRef.current.pause()
|
||||
audioRef.current.currentTime = 0
|
||||
setIsPlaying(false)
|
||||
setCurrentTime(0)
|
||||
const toggleMute = async () => {
|
||||
try {
|
||||
const newVolume = isMuted ? 80 : 0
|
||||
await apiService.post('/api/player/volume', { volume: newVolume })
|
||||
} catch (error) {
|
||||
console.error('Failed to toggle mute:', error)
|
||||
}
|
||||
}
|
||||
|
||||
const togglePlayPause = () => {
|
||||
if (isPlaying) {
|
||||
pause()
|
||||
} else {
|
||||
play()
|
||||
const nextTrack = async () => {
|
||||
try {
|
||||
await apiService.post('/api/player/next')
|
||||
} catch (error) {
|
||||
console.error('Failed to skip to next track:', error)
|
||||
}
|
||||
}
|
||||
|
||||
const seekTo = (time: number) => {
|
||||
if (audioRef.current) {
|
||||
audioRef.current.currentTime = time
|
||||
setCurrentTime(time)
|
||||
const previousTrack = async () => {
|
||||
try {
|
||||
await apiService.post('/api/player/previous')
|
||||
} catch (error) {
|
||||
console.error('Failed to skip to previous track:', error)
|
||||
}
|
||||
}
|
||||
|
||||
const setVolume = (newVolume: number) => {
|
||||
setVolumeState(newVolume)
|
||||
setIsMuted(newVolume === 0)
|
||||
}
|
||||
|
||||
const toggleMute = () => {
|
||||
setIsMuted(!isMuted)
|
||||
}
|
||||
|
||||
const nextTrack = () => {
|
||||
if (playlist.length === 0) return
|
||||
|
||||
const nextIndex = (currentTrackIndex + 1) % playlist.length
|
||||
setCurrentTrackIndex(nextIndex)
|
||||
|
||||
// Auto-play if currently playing
|
||||
if (isPlaying) {
|
||||
setTimeout(() => play(), 100)
|
||||
const playTrack = async (trackIndex: number) => {
|
||||
try {
|
||||
await apiService.post('/api/player/play-track', { index: trackIndex })
|
||||
} catch (error) {
|
||||
console.error('Failed to play track:', error)
|
||||
}
|
||||
}
|
||||
|
||||
const previousTrack = () => {
|
||||
if (playlist.length === 0) return
|
||||
|
||||
const prevIndex = currentTrackIndex === 0 ? playlist.length - 1 : currentTrackIndex - 1
|
||||
setCurrentTrackIndex(prevIndex)
|
||||
|
||||
// Auto-play if currently playing
|
||||
if (isPlaying) {
|
||||
setTimeout(() => play(), 100)
|
||||
}
|
||||
}
|
||||
|
||||
const playRandomTrack = () => {
|
||||
if (playlist.length <= 1) return
|
||||
|
||||
let randomIndex
|
||||
do {
|
||||
randomIndex = Math.floor(Math.random() * playlist.length)
|
||||
} while (randomIndex === currentTrackIndex)
|
||||
|
||||
setCurrentTrackIndex(randomIndex)
|
||||
setTimeout(() => play(), 100)
|
||||
}
|
||||
|
||||
const playTrack = (trackIndex: number) => {
|
||||
if (trackIndex >= 0 && trackIndex < playlist.length) {
|
||||
setCurrentTrackIndex(trackIndex)
|
||||
setTimeout(() => play(), 100)
|
||||
const loadPlaylist = async (playlistId: number) => {
|
||||
try {
|
||||
await apiService.post('/api/player/playlist', { playlist_id: playlistId })
|
||||
} catch (error) {
|
||||
console.error('Failed to load playlist:', error)
|
||||
}
|
||||
}
|
||||
|
||||
const addToPlaylist = (track: Track) => {
|
||||
setPlaylist(prev => [...prev, track])
|
||||
// This would need to be implemented via API
|
||||
console.log('Adding to playlist not yet implemented')
|
||||
}
|
||||
|
||||
const removeFromPlaylist = (trackId: string) => {
|
||||
setPlaylist(prev => {
|
||||
const newPlaylist = prev.filter(track => track.id !== trackId)
|
||||
// Adjust current track index if necessary
|
||||
const removedIndex = prev.findIndex(track => track.id === trackId)
|
||||
if (removedIndex !== -1 && removedIndex < currentTrackIndex) {
|
||||
setCurrentTrackIndex(current => Math.max(0, current - 1))
|
||||
} else if (removedIndex === currentTrackIndex && newPlaylist.length > 0) {
|
||||
setCurrentTrackIndex(current => Math.min(current, newPlaylist.length - 1))
|
||||
}
|
||||
return newPlaylist
|
||||
})
|
||||
// This would need to be implemented via API
|
||||
console.log('Removing from playlist not yet implemented')
|
||||
}
|
||||
|
||||
const clearPlaylist = () => {
|
||||
stop()
|
||||
setPlaylist([])
|
||||
setCurrentTrackIndex(0)
|
||||
// This would need to be implemented via API
|
||||
console.log('Clearing playlist not yet implemented')
|
||||
}
|
||||
|
||||
const setPlayMode = async (mode: PlayMode) => {
|
||||
try {
|
||||
await apiService.post('/api/player/mode', { mode })
|
||||
} catch (error) {
|
||||
console.error('Failed to set play mode:', error)
|
||||
}
|
||||
}
|
||||
|
||||
const toggleMaximize = () => {
|
||||
@@ -303,7 +307,7 @@ export function MusicPlayerProvider({ children }: MusicPlayerProviderProps) {
|
||||
// Playback state
|
||||
isPlaying,
|
||||
currentTime,
|
||||
duration: currentTrack?.duration || 0,
|
||||
duration,
|
||||
volume,
|
||||
isMuted,
|
||||
playMode,
|
||||
@@ -329,6 +333,7 @@ export function MusicPlayerProvider({ children }: MusicPlayerProviderProps) {
|
||||
nextTrack,
|
||||
previousTrack,
|
||||
playTrack,
|
||||
loadPlaylist,
|
||||
addToPlaylist,
|
||||
removeFromPlaylist,
|
||||
clearPlaylist,
|
||||
|
||||
@@ -34,6 +34,8 @@ export const SocketProvider: React.FC<SocketProviderProps> = ({ children }) => {
|
||||
const { user, loading } = useAuth();
|
||||
|
||||
useEffect(() => {
|
||||
console.log('🔌 SocketProvider: Creating socket connection');
|
||||
|
||||
// Create socket connection
|
||||
const newSocket = io("http://localhost:5000", {
|
||||
withCredentials: true, // Include cookies for authentication
|
||||
@@ -42,45 +44,101 @@ export const SocketProvider: React.FC<SocketProviderProps> = ({ children }) => {
|
||||
upgrade: false, // Disable WebSocket upgrade
|
||||
});
|
||||
|
||||
console.log('🔌 SocketProvider: Socket created', {
|
||||
id: newSocket.id,
|
||||
connected: newSocket.connected,
|
||||
disconnected: newSocket.disconnected
|
||||
});
|
||||
|
||||
// Set up event listeners
|
||||
newSocket.on("connect", () => {
|
||||
console.log('✅ SocketIO: Connected successfully', {
|
||||
id: newSocket.id,
|
||||
transport: newSocket.io.engine.transport.name
|
||||
});
|
||||
|
||||
// Test if events work at all
|
||||
console.log('🧪 SocketIO: Sending test event...');
|
||||
newSocket.emit("test_event", { message: "Frontend test" });
|
||||
|
||||
// Send manual test event
|
||||
console.log('🧪 SocketIO: Sending manual test event...');
|
||||
newSocket.emit("manual_test", { message: "Frontend manual test" });
|
||||
|
||||
// Send authentication after connection
|
||||
console.log('🔐 SocketIO: Sending authentication...');
|
||||
newSocket.emit("authenticate", {});
|
||||
});
|
||||
|
||||
newSocket.on("auth_success", () => {
|
||||
newSocket.on("auth_success", (data) => {
|
||||
console.log('🎉 SocketIO: Authentication successful', data);
|
||||
setIsConnected(true);
|
||||
});
|
||||
|
||||
newSocket.on("auth_error", () => {
|
||||
newSocket.on("auth_error", (data) => {
|
||||
console.error('❌ SocketIO: Authentication failed', data);
|
||||
setIsConnected(false);
|
||||
newSocket.disconnect();
|
||||
});
|
||||
|
||||
newSocket.on("disconnect", () => {
|
||||
newSocket.on("disconnect", (reason) => {
|
||||
console.log('🔌 SocketIO: Disconnected', { reason });
|
||||
setIsConnected(false);
|
||||
});
|
||||
|
||||
newSocket.on("connect_error", () => {
|
||||
newSocket.on("connect_error", (error) => {
|
||||
console.error('❌ SocketIO: Connection error', error);
|
||||
setIsConnected(false);
|
||||
});
|
||||
|
||||
// Listen for player state updates
|
||||
newSocket.on("player_state_update", (data) => {
|
||||
console.log('🎵 SocketIO: Player state update received', data);
|
||||
});
|
||||
|
||||
// Listen for credits updates
|
||||
newSocket.on("credits_changed", (data) => {
|
||||
console.log('💰 SocketIO: Credits changed', data);
|
||||
});
|
||||
|
||||
// Listen for test response
|
||||
newSocket.on("test_response", (data) => {
|
||||
console.log('🧪 SocketIO: Test response received', data);
|
||||
});
|
||||
|
||||
setSocket(newSocket);
|
||||
|
||||
// Clean up on unmount
|
||||
return () => {
|
||||
console.log('🔌 SocketProvider: Cleaning up socket');
|
||||
newSocket.close();
|
||||
};
|
||||
}, []);
|
||||
|
||||
// Connect/disconnect based on authentication state
|
||||
useEffect(() => {
|
||||
if (!socket || loading) return;
|
||||
console.log('🔄 SocketProvider: Auth state changed', {
|
||||
hasSocket: !!socket,
|
||||
loading,
|
||||
hasUser: !!user,
|
||||
userEmail: user?.email,
|
||||
isConnected,
|
||||
socketConnected: socket?.connected
|
||||
});
|
||||
|
||||
if (!socket || loading) {
|
||||
console.log('⏳ SocketProvider: Waiting for socket or user loading...');
|
||||
return;
|
||||
}
|
||||
|
||||
if (user && !isConnected) {
|
||||
console.log('🚀 SocketProvider: User authenticated, connecting socket...');
|
||||
socket.connect();
|
||||
} else if (!user && isConnected) {
|
||||
console.log('🔌 SocketProvider: User logged out, disconnecting socket...');
|
||||
socket.disconnect();
|
||||
} else {
|
||||
console.log('⚡ SocketProvider: No action needed', { user: !!user, isConnected });
|
||||
}
|
||||
}, [socket, user, loading, isConnected]);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user