Files
Your Name 13411cfe62 feat: search page redesign + soulseek download fix + cleanup
- Fixed critical Soulseek download bug (backend ignored user's file selection)
- Redesigned search page with Discovery Command Center aesthetic
- Removed 80+ lines dead component code (SoulseekSongsList → soulseekHelpers)
- Added automatic library scan trigger after manual downloads
- New animations: slide-up, float, shimmer
- Magazine-style TopResult card with gradient overlays
- Glassmorphism filter pills with kinetic feedback
- Staggered section reveals with color-coded accent bars
- Fixed h2 header ownership (all in page.tsx)
- Removed unused type exports (DiscoverResponse, SimilarArtistsResponse)

Files: 42 changed, 3055 insertions(+), 2081 deletions(-)
2026-02-09 13:10:03 -06:00

65 lines
1.7 KiB
TypeScript

/**
* Query Events - Typed event system for cache invalidation
*
* Provides a type-safe wrapper around CustomEvent for triggering React Query cache invalidation.
* Events are dispatched when data changes and listeners refetch queries to update the UI.
*/
/**
* Available query event types
*/
export type QueryEventType =
| "audiobook-progress-updated"
| "podcast-progress-updated"
| "mixes-updated";
/**
* Event payload interface - can be extended for event-specific data
*/
export interface QueryEventDetail {
[key: string]: unknown;
}
/**
* Dispatch a typed query event
*
* @param eventType - The type of event to dispatch
* @param detail - Optional event payload data
*
* @example
* dispatchQueryEvent("audiobook-progress-updated", { audiobookId: "123" });
*/
export function dispatchQueryEvent(
eventType: QueryEventType,
detail?: QueryEventDetail
): void {
window.dispatchEvent(
new CustomEvent(eventType, { detail: detail || {} })
);
}
/**
* Subscribe to a typed query event
*
* @param eventType - The type of event to listen for
* @param handler - Callback function to execute when event fires
* @returns Cleanup function to remove the event listener
*
* @example
* const unsubscribe = subscribeQueryEvent("audiobook-progress-updated", () => {
* queryClient.refetchQueries({ queryKey: ["audiobook", id] });
* });
* // Later: unsubscribe();
*/
export function subscribeQueryEvent(
eventType: QueryEventType,
handler: (event: CustomEvent<QueryEventDetail>) => void
): () => void {
const listener = handler as EventListener;
window.addEventListener(eventType, listener);
return () => {
window.removeEventListener(eventType, listener);
};
}