Merge branch 'player'
This commit is contained in:
@@ -23,7 +23,6 @@ export function AuthProvider({ children }: { children: ReactNode }) {
|
|||||||
|
|
||||||
// Listen for refresh token expiration events
|
// Listen for refresh token expiration events
|
||||||
const handleRefreshTokenExpired = () => {
|
const handleRefreshTokenExpired = () => {
|
||||||
console.log('Refresh token expired, logging out user')
|
|
||||||
setUser(null)
|
setUser(null)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,7 +47,8 @@ export function MusicPlayer() {
|
|||||||
|
|
||||||
const progressBarRef = useRef<HTMLDivElement>(null)
|
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
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,7 +99,7 @@ export function MusicPlayer() {
|
|||||||
return (
|
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">
|
<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 */}
|
{/* Thumbnail */}
|
||||||
{currentTrack.thumbnail && (
|
{currentTrack?.thumbnail && (
|
||||||
<div className="relative h-32 w-full overflow-hidden rounded-t-lg">
|
<div className="relative h-32 w-full overflow-hidden rounded-t-lg">
|
||||||
<img
|
<img
|
||||||
src={currentTrack.thumbnail}
|
src={currentTrack.thumbnail}
|
||||||
@@ -122,9 +123,9 @@ export function MusicPlayer() {
|
|||||||
{/* Track info */}
|
{/* Track info */}
|
||||||
<div className="space-y-1">
|
<div className="space-y-1">
|
||||||
<h3 className="font-medium text-sm leading-tight line-clamp-1">
|
<h3 className="font-medium text-sm leading-tight line-clamp-1">
|
||||||
{currentTrack.title}
|
{currentTrack?.title || 'No track selected'}
|
||||||
</h3>
|
</h3>
|
||||||
{currentTrack.artist && (
|
{currentTrack?.artist && (
|
||||||
<p className="text-xs text-muted-foreground line-clamp-1">
|
<p className="text-xs text-muted-foreground line-clamp-1">
|
||||||
{currentTrack.artist}
|
{currentTrack.artist}
|
||||||
</p>
|
</p>
|
||||||
@@ -262,7 +263,7 @@ export function MusicPlayer() {
|
|||||||
{/* Main player area */}
|
{/* Main player area */}
|
||||||
<div className="flex-1 flex flex-col items-center justify-center p-8">
|
<div className="flex-1 flex flex-col items-center justify-center p-8">
|
||||||
{/* Large thumbnail */}
|
{/* Large thumbnail */}
|
||||||
{currentTrack.thumbnail && (
|
{currentTrack?.thumbnail && (
|
||||||
<div className="w-80 h-80 rounded-lg overflow-hidden mb-6 shadow-lg">
|
<div className="w-80 h-80 rounded-lg overflow-hidden mb-6 shadow-lg">
|
||||||
<img
|
<img
|
||||||
src={currentTrack.thumbnail}
|
src={currentTrack.thumbnail}
|
||||||
@@ -274,8 +275,8 @@ export function MusicPlayer() {
|
|||||||
|
|
||||||
{/* Track info */}
|
{/* Track info */}
|
||||||
<div className="text-center mb-6">
|
<div className="text-center mb-6">
|
||||||
<h1 className="text-2xl font-bold mb-2">{currentTrack.title}</h1>
|
<h1 className="text-2xl font-bold mb-2">{currentTrack?.title || 'No track selected'}</h1>
|
||||||
{currentTrack.artist && (
|
{currentTrack?.artist && (
|
||||||
<p className="text-lg text-muted-foreground">{currentTrack.artist}</p>
|
<p className="text-lg text-muted-foreground">{currentTrack.artist}</p>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
import { createContext, useContext, useState, useRef, useEffect, type ReactNode } from 'react'
|
import { createContext, useContext, useState, useRef, useEffect, type ReactNode } from 'react'
|
||||||
|
import { useSocket } from './SocketContext'
|
||||||
|
import { apiService } from '@/services/api'
|
||||||
|
|
||||||
export interface Track {
|
export interface Track {
|
||||||
id: string
|
id: string
|
||||||
@@ -41,6 +43,7 @@ interface MusicPlayerContextType {
|
|||||||
nextTrack: () => void
|
nextTrack: () => void
|
||||||
previousTrack: () => void
|
previousTrack: () => void
|
||||||
playTrack: (trackIndex: number) => void
|
playTrack: (trackIndex: number) => void
|
||||||
|
loadPlaylist: (playlistId: number) => void
|
||||||
addToPlaylist: (track: Track) => void
|
addToPlaylist: (track: Track) => void
|
||||||
removeFromPlaylist: (trackId: string) => void
|
removeFromPlaylist: (trackId: string) => void
|
||||||
clearPlaylist: () => void
|
clearPlaylist: () => void
|
||||||
@@ -63,232 +66,202 @@ interface MusicPlayerProviderProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function MusicPlayerProvider({ children }: MusicPlayerProviderProps) {
|
export function MusicPlayerProvider({ children }: MusicPlayerProviderProps) {
|
||||||
const audioRef = useRef<HTMLAudioElement | null>(null)
|
const { socket } = useSocket()
|
||||||
|
|
||||||
// Playback state
|
// Playback state
|
||||||
const [isPlaying, setIsPlaying] = useState(false)
|
const [isPlaying, setIsPlaying] = useState(false)
|
||||||
const [currentTime, setCurrentTime] = useState(0)
|
const [currentTime, setCurrentTime] = useState(0)
|
||||||
const [duration, setDuration] = useState(0)
|
const [duration, setDuration] = useState(0)
|
||||||
const [volume, setVolumeState] = useState(0.8)
|
const [volume, setVolumeState] = useState(80)
|
||||||
const [isMuted, setIsMuted] = useState(false)
|
const [isMuted, setIsMuted] = useState(false)
|
||||||
const [playMode, setPlayMode] = useState<PlayMode>('continuous')
|
const [playMode, setPlayModeState] = useState<PlayMode>('continuous')
|
||||||
|
|
||||||
// Playlist state
|
// Playlist state
|
||||||
const [currentTrackIndex, setCurrentTrackIndex] = useState(0)
|
const [currentTrackIndex, setCurrentTrackIndex] = useState(0)
|
||||||
const [playlist, setPlaylist] = useState<Track[]>([
|
const [playlist, setPlaylist] = useState<Track[]>([])
|
||||||
{
|
const [currentPlaylistId, setCurrentPlaylistId] = useState<number | null>(null)
|
||||||
id: '1',
|
const [currentTrack, setCurrentTrack] = useState<Track | null>(null)
|
||||||
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'
|
|
||||||
}
|
|
||||||
])
|
|
||||||
|
|
||||||
// UI state
|
// UI state
|
||||||
const [isMinimized, setIsMinimized] = useState(true)
|
const [isMinimized, setIsMinimized] = useState(true)
|
||||||
const [showPlaylist, setShowPlaylist] = useState(false)
|
const [showPlaylist, setShowPlaylist] = useState(false)
|
||||||
|
|
||||||
const currentTrack = playlist[currentTrackIndex] || null
|
// Fetch initial player state on mount
|
||||||
|
|
||||||
// Initialize audio element
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
audioRef.current = new Audio()
|
const fetchInitialState = async () => {
|
||||||
|
try {
|
||||||
|
const response = await apiService.get('/api/player/state')
|
||||||
|
let state = await response.json()
|
||||||
|
|
||||||
const audio = audioRef.current
|
// If no playlist is loaded, try to load the main playlist
|
||||||
|
if (!state.playlist_id) {
|
||||||
|
try {
|
||||||
|
await apiService.post('/api/player/load-main-playlist')
|
||||||
|
// Fetch state again after loading main playlist
|
||||||
|
const newResponse = await apiService.get('/api/player/state')
|
||||||
|
state = await newResponse.json()
|
||||||
|
} catch (loadError) {
|
||||||
|
console.warn('Failed to load main playlist:', loadError)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const handleTimeUpdate = () => {
|
// Update all state from backend
|
||||||
setCurrentTime(audio.currentTime)
|
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)
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to fetch initial player state:', error)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleLoadedMetadata = () => {
|
fetchInitialState()
|
||||||
setDuration(audio.duration)
|
|
||||||
}
|
|
||||||
|
|
||||||
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()
|
|
||||||
}
|
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
// Update audio source when track changes
|
// Listen for real-time player updates via SocketIO
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (audioRef.current && currentTrack) {
|
if (!socket) {
|
||||||
audioRef.current.src = currentTrack.url
|
return;
|
||||||
audioRef.current.load()
|
|
||||||
}
|
}
|
||||||
}, [currentTrack])
|
|
||||||
|
|
||||||
// Update audio volume and mute state
|
const handlePlayerStateUpdate = (state: any) => {
|
||||||
useEffect(() => {
|
setIsPlaying(state.is_playing || false)
|
||||||
if (audioRef.current) {
|
setCurrentTime(state.current_time || 0)
|
||||||
audioRef.current.volume = isMuted ? 0 : volume
|
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)
|
||||||
}
|
}
|
||||||
}, [volume, isMuted])
|
|
||||||
|
|
||||||
const handleTrackEnd = () => {
|
socket.on('player_state_update', handlePlayerStateUpdate)
|
||||||
switch (playMode) {
|
|
||||||
case 'loop-one':
|
return () => {
|
||||||
if (audioRef.current) {
|
socket.off('player_state_update', handlePlayerStateUpdate)
|
||||||
audioRef.current.currentTime = 0
|
}
|
||||||
audioRef.current.play()
|
}, [socket])
|
||||||
}
|
|
||||||
break
|
const play = async () => {
|
||||||
case 'loop-playlist':
|
try {
|
||||||
nextTrack()
|
await apiService.post('/api/player/play')
|
||||||
break
|
} catch (error) {
|
||||||
case 'random':
|
console.error('Failed to play:', error)
|
||||||
playRandomTrack()
|
|
||||||
break
|
|
||||||
case 'continuous':
|
|
||||||
if (currentTrackIndex < playlist.length - 1) {
|
|
||||||
nextTrack()
|
|
||||||
} else {
|
|
||||||
stop()
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const play = () => {
|
const pause = async () => {
|
||||||
if (audioRef.current && currentTrack) {
|
try {
|
||||||
audioRef.current.play()
|
await apiService.post('/api/player/pause')
|
||||||
setIsPlaying(true)
|
} catch (error) {
|
||||||
|
console.error('Failed to pause:', error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const pause = () => {
|
const stop = async () => {
|
||||||
if (audioRef.current) {
|
try {
|
||||||
audioRef.current.pause()
|
await apiService.post('/api/player/stop')
|
||||||
setIsPlaying(false)
|
} catch (error) {
|
||||||
|
console.error('Failed to stop:', error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const stop = () => {
|
const togglePlayPause = async () => {
|
||||||
if (audioRef.current) {
|
|
||||||
audioRef.current.pause()
|
|
||||||
audioRef.current.currentTime = 0
|
|
||||||
setIsPlaying(false)
|
|
||||||
setCurrentTime(0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const togglePlayPause = () => {
|
|
||||||
if (isPlaying) {
|
if (isPlaying) {
|
||||||
pause()
|
await pause()
|
||||||
} else {
|
} else {
|
||||||
play()
|
await play()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const seekTo = (time: number) => {
|
const seekTo = async (time: number) => {
|
||||||
if (audioRef.current) {
|
try {
|
||||||
audioRef.current.currentTime = time
|
const position = duration > 0 ? time / duration : 0
|
||||||
setCurrentTime(time)
|
await apiService.post('/api/player/seek', { position })
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to seek:', error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const setVolume = (newVolume: number) => {
|
const setVolume = async (newVolume: number) => {
|
||||||
setVolumeState(newVolume)
|
try {
|
||||||
setIsMuted(newVolume === 0)
|
await apiService.post('/api/player/volume', { volume: newVolume })
|
||||||
}
|
} catch (error) {
|
||||||
|
console.error('Failed to set volume:', error)
|
||||||
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 previousTrack = () => {
|
const toggleMute = async () => {
|
||||||
if (playlist.length === 0) return
|
try {
|
||||||
|
const newVolume = isMuted ? 80 : 0
|
||||||
const prevIndex = currentTrackIndex === 0 ? playlist.length - 1 : currentTrackIndex - 1
|
await apiService.post('/api/player/volume', { volume: newVolume })
|
||||||
setCurrentTrackIndex(prevIndex)
|
} catch (error) {
|
||||||
|
console.error('Failed to toggle mute:', error)
|
||||||
// Auto-play if currently playing
|
|
||||||
if (isPlaying) {
|
|
||||||
setTimeout(() => play(), 100)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const playRandomTrack = () => {
|
const nextTrack = async () => {
|
||||||
if (playlist.length <= 1) return
|
try {
|
||||||
|
await apiService.post('/api/player/next')
|
||||||
let randomIndex
|
} catch (error) {
|
||||||
do {
|
console.error('Failed to skip to next track:', error)
|
||||||
randomIndex = Math.floor(Math.random() * playlist.length)
|
}
|
||||||
} while (randomIndex === currentTrackIndex)
|
|
||||||
|
|
||||||
setCurrentTrackIndex(randomIndex)
|
|
||||||
setTimeout(() => play(), 100)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const playTrack = (trackIndex: number) => {
|
const previousTrack = async () => {
|
||||||
if (trackIndex >= 0 && trackIndex < playlist.length) {
|
try {
|
||||||
setCurrentTrackIndex(trackIndex)
|
await apiService.post('/api/player/previous')
|
||||||
setTimeout(() => play(), 100)
|
} catch (error) {
|
||||||
|
console.error('Failed to skip to previous track:', error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 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) => {
|
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) => {
|
const removeFromPlaylist = (trackId: string) => {
|
||||||
setPlaylist(prev => {
|
// This would need to be implemented via API
|
||||||
const newPlaylist = prev.filter(track => track.id !== trackId)
|
console.log('Removing from playlist not yet implemented')
|
||||||
// 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
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const clearPlaylist = () => {
|
const clearPlaylist = () => {
|
||||||
stop()
|
// This would need to be implemented via API
|
||||||
setPlaylist([])
|
console.log('Clearing playlist not yet implemented')
|
||||||
setCurrentTrackIndex(0)
|
}
|
||||||
|
|
||||||
|
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 = () => {
|
const toggleMaximize = () => {
|
||||||
@@ -303,7 +276,7 @@ export function MusicPlayerProvider({ children }: MusicPlayerProviderProps) {
|
|||||||
// Playback state
|
// Playback state
|
||||||
isPlaying,
|
isPlaying,
|
||||||
currentTime,
|
currentTime,
|
||||||
duration: currentTrack?.duration || 0,
|
duration,
|
||||||
volume,
|
volume,
|
||||||
isMuted,
|
isMuted,
|
||||||
playMode,
|
playMode,
|
||||||
@@ -329,6 +302,7 @@ export function MusicPlayerProvider({ children }: MusicPlayerProviderProps) {
|
|||||||
nextTrack,
|
nextTrack,
|
||||||
previousTrack,
|
previousTrack,
|
||||||
playTrack,
|
playTrack,
|
||||||
|
loadPlaylist,
|
||||||
addToPlaylist,
|
addToPlaylist,
|
||||||
removeFromPlaylist,
|
removeFromPlaylist,
|
||||||
clearPlaylist,
|
clearPlaylist,
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ export const SocketProvider: React.FC<SocketProviderProps> = ({ children }) => {
|
|||||||
|
|
||||||
// Set up event listeners
|
// Set up event listeners
|
||||||
newSocket.on("connect", () => {
|
newSocket.on("connect", () => {
|
||||||
|
|
||||||
// Send authentication after connection
|
// Send authentication after connection
|
||||||
newSocket.emit("authenticate", {});
|
newSocket.emit("authenticate", {});
|
||||||
});
|
});
|
||||||
@@ -75,7 +76,9 @@ export const SocketProvider: React.FC<SocketProviderProps> = ({ children }) => {
|
|||||||
|
|
||||||
// Connect/disconnect based on authentication state
|
// Connect/disconnect based on authentication state
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!socket || loading) return;
|
if (!socket || loading) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (user && !isConnected) {
|
if (user && !isConnected) {
|
||||||
socket.connect();
|
socket.connect();
|
||||||
|
|||||||
@@ -82,11 +82,8 @@ class ApiService {
|
|||||||
})
|
})
|
||||||
|
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
console.log('Token refreshed successfully')
|
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
console.log('Token refresh failed:', response.status)
|
|
||||||
|
|
||||||
// If refresh token is also expired (401), trigger logout
|
// If refresh token is also expired (401), trigger logout
|
||||||
if (response.status === 401) {
|
if (response.status === 401) {
|
||||||
this.handleLogout()
|
this.handleLogout()
|
||||||
@@ -103,9 +100,6 @@ class ApiService {
|
|||||||
* Handle logout when refresh token expires
|
* Handle logout when refresh token expires
|
||||||
*/
|
*/
|
||||||
private handleLogout() {
|
private handleLogout() {
|
||||||
// Clear any local storage or state if needed
|
|
||||||
console.log('Refresh token expired, user needs to login again')
|
|
||||||
|
|
||||||
// Dispatch a custom event that the AuthContext can listen to
|
// Dispatch a custom event that the AuthContext can listen to
|
||||||
window.dispatchEvent(new CustomEvent('auth:refresh-token-expired'))
|
window.dispatchEvent(new CustomEvent('auth:refresh-token-expired'))
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user