Compare commits
2 Commits
b1eb5c4ab2
...
8f233aaef7
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8f233aaef7 | ||
|
|
e029a692a6 |
@@ -9,14 +9,17 @@ import { Socket, io } from 'socket.io-client'
|
|||||||
import { toast } from 'sonner'
|
import { toast } from 'sonner'
|
||||||
import {
|
import {
|
||||||
AUTH_EVENTS,
|
AUTH_EVENTS,
|
||||||
|
EXTRACTION_EVENTS,
|
||||||
PLAYER_EVENTS,
|
PLAYER_EVENTS,
|
||||||
SOUND_EVENTS,
|
SOUND_EVENTS,
|
||||||
USER_EVENTS,
|
USER_EVENTS,
|
||||||
authEvents,
|
authEvents,
|
||||||
|
extractionEvents,
|
||||||
playerEvents,
|
playerEvents,
|
||||||
soundEvents,
|
soundEvents,
|
||||||
userEvents,
|
userEvents,
|
||||||
} from '../lib/events'
|
} from '../lib/events'
|
||||||
|
import { extractionsService } from '../lib/api/services/extractions'
|
||||||
import { useAuth } from './AuthContext'
|
import { useAuth } from './AuthContext'
|
||||||
|
|
||||||
interface SocketContextType {
|
interface SocketContextType {
|
||||||
@@ -39,6 +42,22 @@ export function SocketProvider({ children }: SocketProviderProps) {
|
|||||||
const [connectionError, setConnectionError] = useState<string | null>(null)
|
const [connectionError, setConnectionError] = useState<string | null>(null)
|
||||||
const [isReconnecting, setIsReconnecting] = useState(false)
|
const [isReconnecting, setIsReconnecting] = useState(false)
|
||||||
|
|
||||||
|
const fetchAndShowOngoingExtractions = useCallback(async () => {
|
||||||
|
try {
|
||||||
|
const processingExtractions = await extractionsService.getProcessingExtractions()
|
||||||
|
|
||||||
|
processingExtractions.forEach(extraction => {
|
||||||
|
const title = extraction.title || 'Processing extraction...'
|
||||||
|
toast.loading(`Extracting: ${title}`, {
|
||||||
|
id: `extraction-${extraction.id}`,
|
||||||
|
duration: Infinity, // Keep it open until status changes
|
||||||
|
})
|
||||||
|
})
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to fetch ongoing extractions:', error)
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
|
||||||
const createSocket = useCallback(() => {
|
const createSocket = useCallback(() => {
|
||||||
if (!user) return null
|
if (!user) return null
|
||||||
|
|
||||||
@@ -59,6 +78,9 @@ export function SocketProvider({ children }: SocketProviderProps) {
|
|||||||
setIsConnected(true)
|
setIsConnected(true)
|
||||||
setConnectionError(null)
|
setConnectionError(null)
|
||||||
setIsReconnecting(false)
|
setIsReconnecting(false)
|
||||||
|
|
||||||
|
// Fetch and show any ongoing extractions
|
||||||
|
fetchAndShowOngoingExtractions()
|
||||||
})
|
})
|
||||||
|
|
||||||
newSocket.on('disconnect', () => {
|
newSocket.on('disconnect', () => {
|
||||||
@@ -107,6 +129,10 @@ export function SocketProvider({ children }: SocketProviderProps) {
|
|||||||
newSocket.on('extraction_status_update', data => {
|
newSocket.on('extraction_status_update', data => {
|
||||||
const { extraction_id, status, title, error } = data
|
const { extraction_id, status, title, error } = data
|
||||||
|
|
||||||
|
// Emit local event for other components to listen to
|
||||||
|
extractionEvents.emit(EXTRACTION_EVENTS.EXTRACTION_STATUS_UPDATED, data)
|
||||||
|
|
||||||
|
// Handle specific status events
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case 'processing':
|
case 'processing':
|
||||||
toast.loading(`Extracting: ${title}`, {
|
toast.loading(`Extracting: ${title}`, {
|
||||||
@@ -119,6 +145,7 @@ export function SocketProvider({ children }: SocketProviderProps) {
|
|||||||
toast.success(`Extraction complete: ${title}`, {
|
toast.success(`Extraction complete: ${title}`, {
|
||||||
duration: 4000,
|
duration: 4000,
|
||||||
})
|
})
|
||||||
|
extractionEvents.emit(EXTRACTION_EVENTS.EXTRACTION_COMPLETED, data)
|
||||||
break
|
break
|
||||||
case 'failed':
|
case 'failed':
|
||||||
toast.dismiss(`extraction-${extraction_id}`)
|
toast.dismiss(`extraction-${extraction_id}`)
|
||||||
@@ -126,12 +153,13 @@ export function SocketProvider({ children }: SocketProviderProps) {
|
|||||||
description: error,
|
description: error,
|
||||||
duration: 6000,
|
duration: 6000,
|
||||||
})
|
})
|
||||||
|
extractionEvents.emit(EXTRACTION_EVENTS.EXTRACTION_FAILED, data)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
return newSocket
|
return newSocket
|
||||||
}, [user])
|
}, [user, fetchAndShowOngoingExtractions])
|
||||||
|
|
||||||
// Handle token refresh - reconnect socket with new token
|
// Handle token refresh - reconnect socket with new token
|
||||||
const handleTokenRefresh = useCallback(() => {
|
const handleTokenRefresh = useCallback(() => {
|
||||||
|
|||||||
@@ -125,6 +125,16 @@ export class ExtractionsService {
|
|||||||
const response = await apiClient.get<GetExtractionsResponse>(url)
|
const response = await apiClient.get<GetExtractionsResponse>(url)
|
||||||
return response
|
return response
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get currently processing extractions
|
||||||
|
*/
|
||||||
|
async getProcessingExtractions(): Promise<ExtractionInfo[]> {
|
||||||
|
const response = await apiClient.get<ExtractionInfo[]>(
|
||||||
|
'/api/v1/extractions/processing/current'
|
||||||
|
)
|
||||||
|
return response
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const extractionsService = new ExtractionsService()
|
export const extractionsService = new ExtractionsService()
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ export const authEvents = new EventEmitter()
|
|||||||
export const playerEvents = new EventEmitter()
|
export const playerEvents = new EventEmitter()
|
||||||
export const soundEvents = new EventEmitter()
|
export const soundEvents = new EventEmitter()
|
||||||
export const userEvents = new EventEmitter()
|
export const userEvents = new EventEmitter()
|
||||||
|
export const extractionEvents = new EventEmitter()
|
||||||
|
|
||||||
// Auth event types
|
// Auth event types
|
||||||
export const AUTH_EVENTS = {
|
export const AUTH_EVENTS = {
|
||||||
@@ -60,3 +61,11 @@ export const SOUND_EVENTS = {
|
|||||||
export const USER_EVENTS = {
|
export const USER_EVENTS = {
|
||||||
USER_CREDITS_CHANGED: 'user_credits_changed',
|
USER_CREDITS_CHANGED: 'user_credits_changed',
|
||||||
} as const
|
} as const
|
||||||
|
|
||||||
|
// Extraction event types
|
||||||
|
export const EXTRACTION_EVENTS = {
|
||||||
|
EXTRACTION_STATUS_UPDATED: 'extraction_status_updated',
|
||||||
|
EXTRACTION_CREATED: 'extraction_created',
|
||||||
|
EXTRACTION_COMPLETED: 'extraction_completed',
|
||||||
|
EXTRACTION_FAILED: 'extraction_failed',
|
||||||
|
} as const
|
||||||
|
|||||||
@@ -15,7 +15,8 @@ import {
|
|||||||
type ExtractionStatus,
|
type ExtractionStatus,
|
||||||
extractionsService,
|
extractionsService,
|
||||||
} from '@/lib/api/services/extractions'
|
} from '@/lib/api/services/extractions'
|
||||||
import { useEffect, useState } from 'react'
|
import { EXTRACTION_EVENTS, extractionEvents } from '@/lib/events'
|
||||||
|
import { useCallback, useEffect, useState } from 'react'
|
||||||
import { toast } from 'sonner'
|
import { toast } from 'sonner'
|
||||||
|
|
||||||
export function ExtractionsPage() {
|
export function ExtractionsPage() {
|
||||||
@@ -51,7 +52,7 @@ export function ExtractionsPage() {
|
|||||||
return () => clearTimeout(handler)
|
return () => clearTimeout(handler)
|
||||||
}, [searchQuery])
|
}, [searchQuery])
|
||||||
|
|
||||||
const fetchExtractions = async () => {
|
const fetchExtractions = useCallback(async () => {
|
||||||
try {
|
try {
|
||||||
setLoading(true)
|
setLoading(true)
|
||||||
setError(null)
|
setError(null)
|
||||||
@@ -74,11 +75,11 @@ export function ExtractionsPage() {
|
|||||||
} finally {
|
} finally {
|
||||||
setLoading(false)
|
setLoading(false)
|
||||||
}
|
}
|
||||||
}
|
}, [debouncedSearchQuery, sortBy, sortOrder, statusFilter, currentPage, pageSize])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchExtractions()
|
fetchExtractions()
|
||||||
}, [debouncedSearchQuery, sortBy, sortOrder, statusFilter, currentPage, pageSize])
|
}, [fetchExtractions])
|
||||||
|
|
||||||
// Reset to page 1 when filters change
|
// Reset to page 1 when filters change
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -87,6 +88,33 @@ export function ExtractionsPage() {
|
|||||||
}
|
}
|
||||||
}, [debouncedSearchQuery, sortBy, sortOrder, statusFilter, pageSize])
|
}, [debouncedSearchQuery, sortBy, sortOrder, statusFilter, pageSize])
|
||||||
|
|
||||||
|
// Listen for extraction events to refresh the list
|
||||||
|
useEffect(() => {
|
||||||
|
const handleExtractionStatusUpdate = () => {
|
||||||
|
fetchExtractions()
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleExtractionCompleted = () => {
|
||||||
|
fetchExtractions()
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleExtractionFailed = () => {
|
||||||
|
fetchExtractions()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Subscribe to extraction events
|
||||||
|
extractionEvents.on(EXTRACTION_EVENTS.EXTRACTION_STATUS_UPDATED, handleExtractionStatusUpdate)
|
||||||
|
extractionEvents.on(EXTRACTION_EVENTS.EXTRACTION_COMPLETED, handleExtractionCompleted)
|
||||||
|
extractionEvents.on(EXTRACTION_EVENTS.EXTRACTION_FAILED, handleExtractionFailed)
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
// Cleanup event listeners
|
||||||
|
extractionEvents.off(EXTRACTION_EVENTS.EXTRACTION_STATUS_UPDATED, handleExtractionStatusUpdate)
|
||||||
|
extractionEvents.off(EXTRACTION_EVENTS.EXTRACTION_COMPLETED, handleExtractionCompleted)
|
||||||
|
extractionEvents.off(EXTRACTION_EVENTS.EXTRACTION_FAILED, handleExtractionFailed)
|
||||||
|
}
|
||||||
|
}, [fetchExtractions])
|
||||||
|
|
||||||
const handlePageChange = (page: number) => {
|
const handlePageChange = (page: number) => {
|
||||||
setCurrentPage(page)
|
setCurrentPage(page)
|
||||||
}
|
}
|
||||||
@@ -112,6 +140,9 @@ export function ExtractionsPage() {
|
|||||||
setUrl('')
|
setUrl('')
|
||||||
setShowCreateDialog(false)
|
setShowCreateDialog(false)
|
||||||
|
|
||||||
|
// Emit event for new extraction created
|
||||||
|
extractionEvents.emit(EXTRACTION_EVENTS.EXTRACTION_CREATED, response.extraction)
|
||||||
|
|
||||||
// Refresh the extractions list
|
// Refresh the extractions list
|
||||||
fetchExtractions()
|
fetchExtractions()
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|||||||
Reference in New Issue
Block a user