From 301a162e7175139bda99785fcd8e81b4dcd3630e Mon Sep 17 00:00:00 2001 From: SergeantPanda Date: Sat, 13 Sep 2025 20:16:14 -0500 Subject: [PATCH] Switch to normal notifications --- frontend/src/WebSocket.jsx | 69 ++++++++++- .../src/components/tables/StreamsTable.jsx | 117 ++---------------- 2 files changed, 71 insertions(+), 115 deletions(-) diff --git a/frontend/src/WebSocket.jsx b/frontend/src/WebSocket.jsx index ef0a9cfc..c786ff88 100644 --- a/frontend/src/WebSocket.jsx +++ b/frontend/src/WebSocket.jsx @@ -571,11 +571,56 @@ export const WebsocketProvider = ({ children }) => { break; - case 'bulk_channel_creation_progress': - // Handle completion status globally to refresh channels - if (parsedEvent.data.status === 'completed') { + case 'bulk_channel_creation_progress': { + // Handle progress updates with persistent notifications like stream rehash + const data = parsedEvent.data; + + if (data.status === 'starting') { + notifications.show({ + id: 'bulk-channel-creation-progress', // Persistent ID + title: 'Bulk Channel Creation Started', + message: data.message || 'Starting bulk channel creation...', + color: 'blue.5', + autoClose: false, // Don't auto-close + withCloseButton: false, // No close button during processing + loading: true, // Show loading indicator + }); + } else if ( + data.status === 'processing' || + data.status === 'creating_logos' || + data.status === 'creating_channels' + ) { + // Calculate progress percentage + const progressPercent = + data.total > 0 + ? Math.round((data.progress / data.total) * 100) + : 0; + + // Update the existing notification with progress + notifications.update({ + id: 'bulk-channel-creation-progress', + title: 'Bulk Channel Creation in Progress', + message: `${progressPercent}% complete - ${data.message}`, + color: 'blue.5', + autoClose: false, + withCloseButton: false, + loading: true, + }); + } else if (data.status === 'completed') { + // Update to completion state + notifications.update({ + id: 'bulk-channel-creation-progress', + title: 'Bulk Channel Creation Complete', + message: `Successfully created ${data.created_count || 'multiple'} channels${data.error_count > 0 ? ` (${data.error_count} errors)` : ''}`, + color: 'green.5', + autoClose: 8000, // Auto-close after completion + withCloseButton: true, // Allow manual close + loading: false, // Remove loading indicator + }); + + // Refresh channels try { - await API.requeryChannels(); + await useChannelsStore.getState().fetchChannels(); console.log( 'Channels refreshed after bulk creation completion' ); @@ -585,11 +630,25 @@ export const WebsocketProvider = ({ children }) => { error ); } + } else if (data.status === 'failed') { + // Update to error state + notifications.update({ + id: 'bulk-channel-creation-progress', + title: 'Bulk Channel Creation Failed', + message: + data.error || + 'An error occurred during bulk channel creation', + color: 'red.5', + autoClose: 12000, // Auto-close after longer delay for errors + withCloseButton: true, // Allow manual close + loading: false, // Remove loading indicator + }); } - // Pass through to individual components for progress updates + // Pass through to individual components for any additional handling setVal(parsedEvent); break; + } default: console.error( diff --git a/frontend/src/components/tables/StreamsTable.jsx b/frontend/src/components/tables/StreamsTable.jsx index 7424a656..87cf57bb 100644 --- a/frontend/src/components/tables/StreamsTable.jsx +++ b/frontend/src/components/tables/StreamsTable.jsx @@ -1,17 +1,10 @@ -import React, { - useEffect, - useMemo, - useCallback, - useState, - useContext, -} from 'react'; +import React, { useEffect, useMemo, useCallback, useState } from 'react'; import API from '../../api'; import StreamForm from '../forms/Stream'; import usePlaylistsStore from '../../store/playlists'; import useChannelsStore from '../../store/channels'; import useLogosStore from '../../store/logos'; import { copyToClipboard, useDebounce } from '../../utils'; -import { WebsocketContext } from '../../WebSocket'; import { SquarePlus, ListPlus, @@ -203,12 +196,7 @@ const StreamsTable = () => { const [isLoading, setIsLoading] = useState(true); const [sorting, setSorting] = useState([{ id: 'name', desc: '' }]); const [selectedStreamIds, setSelectedStreamIds] = useState([]); - const [isCreatingChannels, setIsCreatingChannels] = useState(false); - const [creationProgress, setCreationProgress] = useState(''); - const [activeTaskId, setActiveTaskId] = useState(null); - // WebSocket context for real-time updates - const [, , wsValue] = useContext(WebsocketContext); // const [allRowsSelected, setAllRowsSelected] = useState(false); // Add local storage for page size @@ -436,9 +424,6 @@ const StreamsTable = () => { const createChannelsFromStreams = async () => { if (selectedStreamIds.length === 0) return; - setIsCreatingChannels(true); - setCreationProgress('Starting bulk channel creation...'); - try { const selectedChannelProfileId = useChannelsStore.getState().selectedProfileId; @@ -449,21 +434,15 @@ const StreamsTable = () => { selectedChannelProfileId !== '0' ? [selectedChannelProfileId] : null ); - setActiveTaskId(response.task_id); - setCreationProgress( - `Task started for ${response.stream_count} streams. Processing in background...` - ); - console.log( `Bulk creation task started: ${response.task_id} for ${response.stream_count} streams` ); - console.log('Active task ID set to:', response.task_id); + + // Clear selection since the task has started + setSelectedStreamIds([]); } catch (error) { console.error('Error starting bulk channel creation:', error); - setCreationProgress('Error starting bulk channel creation'); - setIsCreatingChannels(false); - // Clear error message after delay - setTimeout(() => setCreationProgress(''), 5000); + // Error notifications will be handled by WebSocket } }; @@ -689,69 +668,6 @@ const StreamsTable = () => { fetchData(); }, [fetchData]); - // Listen for WebSocket updates for bulk creation progress - useEffect(() => { - if (wsValue) { - console.log('WebSocket message received:', wsValue); - - if ( - wsValue.data && - wsValue.data.type === 'bulk_channel_creation_progress' - ) { - const data = wsValue.data; - console.log('Bulk creation progress update:', data); - - // Only handle progress for our active task - if (activeTaskId && data.task_id === activeTaskId) { - const progress = data.progress || 0; - const total = data.total || 0; - const status = data.status; - const message = data.message; - - console.log( - `Task ${activeTaskId} progress: ${progress}/${total} (${status})` - ); - - if (status === 'completed') { - setCreationProgress( - `✅ Completed! Created ${data.created_count} channels` - ); - setIsCreatingChannels(false); - setActiveTaskId(null); - - // Clear selection and refresh data - setSelectedStreamIds([]); - fetchData(); - // Note: API.requeryChannels() is called by WebSocket handler globally - - // Clear success message after delay - setTimeout(() => setCreationProgress(''), 5000); - } else if (status === 'failed') { - setCreationProgress( - `❌ Task failed: ${data.error || 'Unknown error'}` - ); - setIsCreatingChannels(false); - setActiveTaskId(null); - - // Clear error message after longer delay - setTimeout(() => setCreationProgress(''), 10000); - } else { - // Update progress - const progressPercent = - total > 0 ? Math.round((progress / total) * 100) : 0; - setCreationProgress( - `${message} (${progress}/${total} - ${progressPercent}%)` - ); - } - } else { - console.log( - `Ignoring progress for task ${data.task_id}, active task is ${activeTaskId}` - ); - } - } - } - }, [wsValue, activeTaskId, fetchData]); - return ( <> { size="xs" onClick={createChannelsFromStreams} p={5} - disabled={selectedStreamIds.length == 0 || isCreatingChannels} - loading={isCreatingChannels} + disabled={selectedStreamIds.length == 0} > - {isCreatingChannels - ? creationProgress || 'Creating Channels...' - : `Create Channels (${selectedStreamIds.length})`} + {`Create Channels (${selectedStreamIds.length})`}