Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 103 additions & 14 deletions smnb/app/dashboard/studio/controls/Controls.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { useSimpleLiveFeedStore } from '@/lib/stores/livefeed/simpleLiveFeedStor
import { useHostAgentStore } from '@/lib/stores/host/hostAgentStore';
import { useProducerStore } from '@/lib/stores/producer/producerStore';
import { useApiKeyStore } from '@/lib/stores/apiKeyStore';
import { useQueueManagerStore } from '@/lib/stores/queueManagerStore';
// import { useEditorAgentStore } from '@/lib/stores/host/editorAgentStore'; // Commented out - editor functionality disabled
import { StudioMode } from '../Studio';
import {
Expand Down Expand Up @@ -108,7 +109,9 @@ export default function Controls({ mode, onModeChange }: ControlsProps) {
start: startHostBroadcasting,
stop: stopHostBroadcasting,
stats: hostStats,
processLiveFeedPost
processLiveFeedPost,
getQueueStatus,
getQueueBySubreddit
} = useHostAgentStore();

const {
Expand All @@ -123,6 +126,14 @@ export default function Controls({ mode, onModeChange }: ControlsProps) {
hasValidKey: hasValidApiKey
} = useApiKeyStore();

const {
initializeQueueManager,
clearQueueBySubreddit,
clearAllQueues,
refreshStats,
getDetailedStatus
} = useQueueManagerStore();

// Editor agent store - commented out
/*
const {
Expand Down Expand Up @@ -226,19 +237,34 @@ export default function Controls({ mode, onModeChange }: ControlsProps) {
}
};

const handleRemoveSubreddit = (subreddit: string) => {
// Remove from enabledDefaults
const updatedEnabledDefaults = enabledDefaults.filter(s => s !== subreddit);
setEnabledDefaults(updatedEnabledDefaults);

// Also remove from customSubreddits if it exists there
const updatedCustom = customSubreddits.filter(s => s !== subreddit);
setCustomSubreddits(updatedCustom);

// Update the selected subreddits
updateSelectedSubreddits(updatedEnabledDefaults, updatedCustom);

console.log(`🗑️ Removed subreddit: ${subreddit}`);
const handleRemoveSubreddit = async (subreddit: string) => {
try {
// Remove from enabledDefaults
const updatedEnabledDefaults = enabledDefaults.filter(s => s !== subreddit);
setEnabledDefaults(updatedEnabledDefaults);

// Also remove from customSubreddits if it exists there
const updatedCustom = customSubreddits.filter(s => s !== subreddit);
setCustomSubreddits(updatedCustom);

// Update the selected subreddits
updateSelectedSubreddits(updatedEnabledDefaults, updatedCustom);

console.log(`🗑️ Removed subreddit: ${subreddit}`);

// Clear queue items for this subreddit
try {
const result = await clearQueueBySubreddit(subreddit);
if (result.totalCleared > 0) {
console.log(`✅ Queue cleared for r/${subreddit}: ${result.totalCleared} items (Host: ${result.hostQueueCleared}, Scheduled: ${result.scheduledPostsCleared})`);
}
} catch (error) {
console.warn(`⚠️ Failed to clear queue for r/${subreddit}:`, error);
// Don't block the UI operation if queue clearing fails
}
} catch (error) {
console.error(`❌ Error removing subreddit ${subreddit}:`, error);
}
};

const handleToggleDefaultSubreddit = (subreddit: string) => {
Expand Down Expand Up @@ -334,6 +360,11 @@ export default function Controls({ mode, onModeChange }: ControlsProps) {
updateSelectedSubreddits(enabledDefaults, customSubreddits);
}, [enabledDefaults, customSubreddits, updateSelectedSubreddits]);

// Initialize queue manager
useEffect(() => {
initializeQueueManager();
}, [initializeQueueManager]);

return (
<div className="bg-card border border-border rounded-t-xs rounded-b-lg shadow-sm flex flex-col min-h-0">
{/* Compact Header */}
Expand Down Expand Up @@ -670,6 +701,64 @@ export default function Controls({ mode, onModeChange }: ControlsProps) {
</span>
</div>
</div>

{/* Queue Status */}
<div className="border-t border-border/20 pt-1 mt-1">
<div className="flex items-center justify-between">
<span className="text-xs text-muted-foreground/70">Queue</span>
<div className="flex items-center gap-1">
<span className="text-xs font-mono text-muted-foreground">
{(() => {
const queueStatus = getQueueStatus();
const hostQueue = getQueueBySubreddit();
const totalItems = Object.values(hostQueue).reduce((sum: number, count: number) => sum + count, 0);
return totalItems;
})()}
</span>
{(() => {
const hostQueue = getQueueBySubreddit();
const totalItems = Object.values(hostQueue).reduce((sum: number, count: number) => sum + count, 0);
return totalItems > 0 ? (
<button
onClick={async () => {
try {
const result = await clearAllQueues();
console.log(`✅ Cleared all queues: ${result.totalCleared} items`);
} catch (error) {
console.error('❌ Failed to clear all queues:', error);
}
}}
className="text-xs px-1 py-0.5 text-red-400 hover:text-red-300 transition-colors cursor-pointer bg-red-500/10 rounded"
title="Clear all queue items"
>
×
</button>
) : null;
})()}
</div>
</div>
{(() => {
const hostQueue = getQueueBySubreddit();
const topSubreddits = Object.entries(hostQueue)
.sort(([,a], [,b]) => (b as number) - (a as number))
.slice(0, 3);

return topSubreddits.length > 0 ? (
<div className="mt-1 space-y-0.5">
{topSubreddits.map(([subreddit, count]) => (
<div key={subreddit} className="flex items-center justify-between">
<span className="text-xs text-muted-foreground/50 truncate max-w-16">
r/{subreddit}
</span>
<span className="text-xs font-mono text-muted-foreground/70">
{count}
</span>
</div>
))}
</div>
) : null;
})()}
</div>
</div>
</div>
</div>
Expand Down
30 changes: 30 additions & 0 deletions smnb/lib/services/host/hostAgentService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,23 @@ export class HostAgentService extends EventEmitter {
this.emit('queue:updated', 0);
}

public clearQueueBySubreddit(subreddit: string): void {
const beforeLength = this.state.narrationQueue.length;
this.state.narrationQueue = this.state.narrationQueue.filter(narration => {
const itemSubreddit = narration.metadata?.originalItem?.subreddit;
return itemSubreddit !== subreddit;
});
const afterLength = this.state.narrationQueue.length;
const removedCount = beforeLength - afterLength;

console.log(`🗑️ Cleared ${removedCount} narration(s) from queue for subreddit: r/${subreddit}`);
this.emit('queue:updated', this.state.narrationQueue.length);

if (removedCount > 0) {
this.emit('queue:subreddit-cleared', { subreddit, removedCount });
}
}

public getQueueStatus(): {
length: number;
isProcessing: boolean;
Expand All @@ -368,6 +385,19 @@ export class HostAgentService extends EventEmitter {
};
}

public getQueueBySubreddit(): { [subreddit: string]: number } {
const subredditCounts: { [subreddit: string]: number } = {};

this.state.narrationQueue.forEach(narration => {
const subreddit = narration.metadata?.originalItem?.subreddit;
if (subreddit) {
subredditCounts[subreddit] = (subredditCounts[subreddit] || 0) + 1;
}
});

return subredditCounts;
}

// 🎯 DUPLICATE DETECTION UTILITIES

/**
Expand Down
35 changes: 35 additions & 0 deletions smnb/lib/services/livefeed/schedulerService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,41 @@ export class SchedulerService {
categoryDistribution,
};
}

/**
* Clear all scheduled posts for a specific subreddit
*/
clearScheduledPostsBySubreddit(subreddit: string): number {
const beforeLength = this.scheduledPosts.length;
this.scheduledPosts = this.scheduledPosts.filter(post => post.subreddit !== subreddit);
const removedCount = beforeLength - this.scheduledPosts.length;

console.log(`🗑️ SchedulerService: Cleared ${removedCount} scheduled post(s) for subreddit: r/${subreddit}`);
return removedCount;
}

/**
* Get count of scheduled posts by subreddit
*/
getScheduledPostsBySubreddit(): { [subreddit: string]: number } {
const subredditCounts: { [subreddit: string]: number } = {};

this.scheduledPosts.forEach(post => {
subredditCounts[post.subreddit] = (subredditCounts[post.subreddit] || 0) + 1;
});

return subredditCounts;
}

/**
* Clear all scheduled posts (for debugging/management)
*/
clearAllScheduledPosts(): number {
const count = this.scheduledPosts.length;
this.scheduledPosts = [];
console.log(`🗑️ SchedulerService: Cleared all ${count} scheduled posts`);
return count;
}
}

export const schedulerService = new SchedulerService();
Loading