@djangocfg/ui-tools 2.1.208 → 2.1.210
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-CDP3K6BI.mjs → chunk-52WXASRO.mjs} +29 -16
- package/dist/chunk-52WXASRO.mjs.map +1 -0
- package/dist/{chunk-HJMDAPQH.cjs → chunk-DF6ORMTF.cjs} +29 -16
- package/dist/chunk-DF6ORMTF.cjs.map +1 -0
- package/dist/{components-F2ZYYCH4.cjs → components-4Z2JIRZI.cjs} +12 -12
- package/dist/{components-3RJ5Y3TB.mjs.map → components-4Z2JIRZI.cjs.map} +1 -1
- package/dist/{components-3RJ5Y3TB.mjs → components-YWYUZQIH.mjs} +3 -3
- package/dist/{components-F2ZYYCH4.cjs.map → components-YWYUZQIH.mjs.map} +1 -1
- package/dist/index.cjs +39 -39
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.mjs +4 -4
- package/package.json +6 -6
- package/src/tools/AudioPlayer/AudioPlayer.story.tsx +11 -0
- package/src/tools/AudioPlayer/README.md +1 -0
- package/src/tools/AudioPlayer/components/HybridCompactPlayer.tsx +12 -2
- package/src/tools/AudioPlayer/components/HybridWaveform.tsx +19 -12
- package/dist/chunk-CDP3K6BI.mjs.map +0 -1
- package/dist/chunk-HJMDAPQH.cjs.map +0 -1
|
@@ -6,6 +6,7 @@ import { useTypedT } from '@djangocfg/i18n';
|
|
|
6
6
|
import { create } from 'zustand';
|
|
7
7
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
8
8
|
import { cn, createMediaLogger } from '@djangocfg/ui-core/lib';
|
|
9
|
+
import { useThemeColor } from '@djangocfg/ui-core/styles/palette';
|
|
9
10
|
import { cn as cn$2 } from '@djangocfg/ui-core';
|
|
10
11
|
|
|
11
12
|
var useAudioBusStore = create((set) => ({
|
|
@@ -529,12 +530,18 @@ var HybridWaveform = memo(/* @__PURE__ */ __name(function HybridWaveform2({
|
|
|
529
530
|
barWidth = 3,
|
|
530
531
|
barGap = 2,
|
|
531
532
|
barRadius = 2,
|
|
532
|
-
progressColor
|
|
533
|
-
waveColor
|
|
534
|
-
bufferedColor
|
|
533
|
+
progressColor,
|
|
534
|
+
waveColor,
|
|
535
|
+
bufferedColor,
|
|
535
536
|
className,
|
|
536
537
|
onSeek
|
|
537
538
|
}) {
|
|
539
|
+
const themePrimary = useThemeColor("primary");
|
|
540
|
+
const themePrimaryWave = useThemeColor("primary", 0.3);
|
|
541
|
+
const themePrimaryBuffered = useThemeColor("primary", 0.15);
|
|
542
|
+
const resolvedProgressColor = progressColor ?? themePrimary;
|
|
543
|
+
const resolvedWaveColor = waveColor ?? themePrimaryWave;
|
|
544
|
+
const resolvedBufferedColor = bufferedColor ?? themePrimaryBuffered;
|
|
538
545
|
const canvasRef = useRef(null);
|
|
539
546
|
const containerRef = useRef(null);
|
|
540
547
|
const animationRef = useRef(null);
|
|
@@ -568,7 +575,7 @@ var HybridWaveform = memo(/* @__PURE__ */ __name(function HybridWaveform2({
|
|
|
568
575
|
}
|
|
569
576
|
ctx.clearRect(0, 0, width, canvasHeight);
|
|
570
577
|
if (state.buffered && state.duration > 0) {
|
|
571
|
-
ctx.fillStyle =
|
|
578
|
+
ctx.fillStyle = resolvedBufferedColor;
|
|
572
579
|
for (let i = 0; i < state.buffered.length; i++) {
|
|
573
580
|
const start = state.buffered.start(i) / state.duration * width;
|
|
574
581
|
const end = state.buffered.end(i) / state.duration * width;
|
|
@@ -589,7 +596,7 @@ var HybridWaveform = memo(/* @__PURE__ */ __name(function HybridWaveform2({
|
|
|
589
596
|
}
|
|
590
597
|
const x = i * (barWidth + barGap) * dpr;
|
|
591
598
|
const y = (canvasHeight - barHeight) / 2;
|
|
592
|
-
ctx.fillStyle = x < progressX ?
|
|
599
|
+
ctx.fillStyle = x < progressX ? resolvedProgressColor : resolvedWaveColor;
|
|
593
600
|
const radius = barRadius * dpr;
|
|
594
601
|
const rectWidth = barWidth * dpr;
|
|
595
602
|
ctx.beginPath();
|
|
@@ -608,9 +615,9 @@ var HybridWaveform = memo(/* @__PURE__ */ __name(function HybridWaveform2({
|
|
|
608
615
|
barWidth,
|
|
609
616
|
barGap,
|
|
610
617
|
barRadius,
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
618
|
+
resolvedProgressColor,
|
|
619
|
+
resolvedWaveColor,
|
|
620
|
+
resolvedBufferedColor
|
|
614
621
|
]);
|
|
615
622
|
const renderStatic = useCallback(() => {
|
|
616
623
|
const canvas = canvasRef.current;
|
|
@@ -621,7 +628,7 @@ var HybridWaveform = memo(/* @__PURE__ */ __name(function HybridWaveform2({
|
|
|
621
628
|
const dpr = window.devicePixelRatio || 1;
|
|
622
629
|
ctx.clearRect(0, 0, width, canvasHeight);
|
|
623
630
|
if (state.buffered && state.duration > 0) {
|
|
624
|
-
ctx.fillStyle =
|
|
631
|
+
ctx.fillStyle = resolvedBufferedColor;
|
|
625
632
|
for (let i = 0; i < state.buffered.length; i++) {
|
|
626
633
|
const start = state.buffered.start(i) / state.duration * width;
|
|
627
634
|
const end = state.buffered.end(i) / state.duration * width;
|
|
@@ -630,16 +637,16 @@ var HybridWaveform = memo(/* @__PURE__ */ __name(function HybridWaveform2({
|
|
|
630
637
|
}
|
|
631
638
|
const progress = state.duration > 0 ? state.currentTime / state.duration : 0;
|
|
632
639
|
const progressWidth = width * progress;
|
|
633
|
-
ctx.fillStyle =
|
|
640
|
+
ctx.fillStyle = resolvedWaveColor;
|
|
634
641
|
ctx.fillRect(0, canvasHeight / 2 - 2 * dpr, width, 4 * dpr);
|
|
635
|
-
ctx.fillStyle =
|
|
642
|
+
ctx.fillStyle = resolvedProgressColor;
|
|
636
643
|
ctx.fillRect(0, canvasHeight / 2 - 2 * dpr, progressWidth, 4 * dpr);
|
|
637
644
|
if (progress > 0) {
|
|
638
645
|
ctx.beginPath();
|
|
639
646
|
ctx.arc(progressWidth, canvasHeight / 2, 6 * dpr, 0, Math.PI * 2);
|
|
640
647
|
ctx.fill();
|
|
641
648
|
}
|
|
642
|
-
}, [state.buffered, state.duration, state.currentTime,
|
|
649
|
+
}, [state.buffered, state.duration, state.currentTime, resolvedProgressColor, resolvedWaveColor, resolvedBufferedColor]);
|
|
643
650
|
useEffect(() => {
|
|
644
651
|
const container = containerRef.current;
|
|
645
652
|
const canvas = canvasRef.current;
|
|
@@ -1535,6 +1542,7 @@ function HybridCompactPlayer({
|
|
|
1535
1542
|
initialVolume = 1,
|
|
1536
1543
|
waveformMode = "frequency",
|
|
1537
1544
|
showTimer = true,
|
|
1545
|
+
buttonSize = "md",
|
|
1538
1546
|
className,
|
|
1539
1547
|
onPlay,
|
|
1540
1548
|
onPause,
|
|
@@ -1558,6 +1566,7 @@ function HybridCompactPlayer({
|
|
|
1558
1566
|
title,
|
|
1559
1567
|
waveformMode,
|
|
1560
1568
|
showTimer,
|
|
1569
|
+
buttonSize,
|
|
1561
1570
|
className
|
|
1562
1571
|
}
|
|
1563
1572
|
)
|
|
@@ -1565,7 +1574,11 @@ function HybridCompactPlayer({
|
|
|
1565
1574
|
);
|
|
1566
1575
|
}
|
|
1567
1576
|
__name(HybridCompactPlayer, "HybridCompactPlayer");
|
|
1568
|
-
|
|
1577
|
+
var BUTTON_SIZE = {
|
|
1578
|
+
sm: "h-6 w-6",
|
|
1579
|
+
md: "h-8 w-8"
|
|
1580
|
+
};
|
|
1581
|
+
function HybridCompactPlayerInner({ title, waveformMode, showTimer, buttonSize, className }) {
|
|
1569
1582
|
const { state, controls } = useHybridAudioContext();
|
|
1570
1583
|
const isLoading = !state.isReady;
|
|
1571
1584
|
return /* @__PURE__ */ jsxs("div", { className: cn$2("flex items-center gap-2 w-full", className), children: [
|
|
@@ -1574,7 +1587,7 @@ function HybridCompactPlayerInner({ title, waveformMode, showTimer, className })
|
|
|
1574
1587
|
{
|
|
1575
1588
|
variant: "outline",
|
|
1576
1589
|
size: "icon",
|
|
1577
|
-
className: "
|
|
1590
|
+
className: cn$2(BUTTON_SIZE[buttonSize], "flex-shrink-0"),
|
|
1578
1591
|
onClick: controls.togglePlay,
|
|
1579
1592
|
disabled: !state.isReady && !isLoading,
|
|
1580
1593
|
title: title ?? (state.isPlaying ? "Pause" : "Play"),
|
|
@@ -1602,5 +1615,5 @@ function HybridCompactPlayerInner({ title, waveformMode, showTimer, className })
|
|
|
1602
1615
|
__name(HybridCompactPlayerInner, "HybridCompactPlayerInner");
|
|
1603
1616
|
|
|
1604
1617
|
export { AudioReactiveCover, COLOR_SCHEMES2 as COLOR_SCHEMES, COLOR_SCHEME_INFO, EFFECT_ANIMATIONS, GlowEffect, HybridAudioPlayer, HybridAudioProvider, HybridCompactPlayer, HybridSimplePlayer, HybridWaveform, INTENSITY_CONFIG, INTENSITY_INFO, MeshEffect, OrbsEffect, SpotlightEffect, VARIANT_INFO, VisualizationProvider, calculateGlowLayers, calculateMeshGradients, calculateOrbs, calculateSpotlight, formatTime, getColors, getEffectConfig, prepareEffectColors, useAudioBus, useAudioBusStore, useAudioVisualization, useHybridAudio, useHybridAudioAnalysis, useHybridAudioContext, useHybridAudioControls, useHybridAudioLevels, useHybridAudioState, useHybridWebAudio, useVisualization };
|
|
1605
|
-
//# sourceMappingURL=chunk-
|
|
1606
|
-
//# sourceMappingURL=chunk-
|
|
1618
|
+
//# sourceMappingURL=chunk-52WXASRO.mjs.map
|
|
1619
|
+
//# sourceMappingURL=chunk-52WXASRO.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/tools/AudioPlayer/hooks/useAudioBus.ts","../src/tools/AudioPlayer/hooks/useHybridAudio.ts","../src/tools/AudioPlayer/hooks/useHybridAudioAnalysis.ts","../src/tools/AudioPlayer/hooks/useVisualization.tsx","../src/tools/AudioPlayer/context/HybridAudioProvider.tsx","../src/tools/AudioPlayer/components/HybridWaveform.tsx","../src/tools/AudioPlayer/utils/formatTime.ts","../src/tools/AudioPlayer/utils/debug.ts","../src/tools/AudioPlayer/components/HybridAudioPlayer.tsx","../src/tools/AudioPlayer/effects/index.ts","../src/tools/AudioPlayer/components/ReactiveCover/effects/GlowEffect.tsx","../src/tools/AudioPlayer/components/ReactiveCover/effects/OrbsEffect.tsx","../src/tools/AudioPlayer/components/ReactiveCover/effects/SpotlightEffect.tsx","../src/tools/AudioPlayer/components/ReactiveCover/effects/MeshEffect.tsx","../src/tools/AudioPlayer/components/ReactiveCover/AudioReactiveCover.tsx","../src/tools/AudioPlayer/components/HybridSimplePlayer.tsx","../src/tools/AudioPlayer/components/HybridCompactPlayer.tsx"],"names":["useRef","useCallback","useEffect","useState","createContext","useMemo","jsx","useContext","HybridWaveform","cn","memo","HybridAudioPlayer","COLOR_SCHEMES","jsxs","Fragment","Loader2","Pause","Play"],"mappings":"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","file":"chunk-52WXASRO.mjs","sourcesContent":["'use client';\n\n/**\n * useAudioBus — Global audio exclusivity via Zustand store.\n *\n * Ensures only one audio player plays at a time across the entire page.\n * No provider needed — singleton store, works anywhere in the tree.\n *\n * Also integrates with @djangocfg/ui-tools AudioPlayer automatically\n * (wired into useHybridAudio).\n *\n * @example\n * const { announce } = useAudioBus('my-player-id', () => pause());\n *\n * // When playback starts:\n * announce(); // all other players will pause\n */\n\nimport { useEffect, useRef, useCallback } from 'react';\nimport { create } from 'zustand';\n\n// =============================================================================\n// Store\n// =============================================================================\n\ninterface AudioBusStore {\n /** ID of the currently active (playing) player, null if none */\n activeId: string | null;\n setActiveId: (id: string | null) => void;\n}\n\nexport const useAudioBusStore = create<AudioBusStore>((set) => ({\n activeId: null,\n setActiveId: (id) => set({ activeId: id }),\n}));\n\n// =============================================================================\n// Hook\n// =============================================================================\n\nexport interface UseAudioBusReturn {\n /** Broadcast: this player is now playing — all others should stop */\n announce: () => void;\n /** Release: this player stopped (clears activeId if it was ours) */\n release: () => void;\n}\n\n/**\n * @param playerId Stable unique ID for this player instance\n * @param onStop Called when another player announces — should pause this player\n */\nexport function useAudioBus(playerId: string, onStop: () => void): UseAudioBusReturn {\n const onStopRef = useRef(onStop);\n onStopRef.current = onStop;\n\n const setActiveId = useAudioBusStore((s) => s.setActiveId);\n\n // Subscribe to store changes — if another player becomes active, stop this one\n useEffect(() => {\n return useAudioBusStore.subscribe((state) => {\n if (state.activeId !== null && state.activeId !== playerId) {\n onStopRef.current();\n }\n });\n }, [playerId]);\n\n const announce = useCallback(() => {\n setActiveId(playerId);\n }, [playerId, setActiveId]);\n\n const release = useCallback(() => {\n useAudioBusStore.setState((s) => s.activeId === playerId ? { activeId: null } : s);\n }, [playerId]);\n\n return { announce, release };\n}\n","'use client';\n\n/**\n * useHybridAudio - Hybrid audio hook combining HTML5 audio + Web Audio API\n *\n * Uses native HTML5 <audio> for playback (no crackling, native streaming)\n * and Web Audio API only for visualization (AnalyserNode).\n *\n * Audio routing:\n * source -> destination (single path for playback)\n * source -> analyser (parallel path for visualization only, no output)\n */\n\nimport { useCallback, useEffect, useId, useRef, useState } from 'react';\nimport { useAudioBus } from './useAudioBus';\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport interface UseHybridAudioOptions {\n src: string;\n autoPlay?: boolean;\n initialVolume?: number;\n loop?: boolean;\n crossOrigin?: 'anonymous' | 'use-credentials';\n /** Set to true to opt out of global audio bus (player won't stop others and won't be stopped) */\n excludeFromBus?: boolean;\n onPlay?: () => void;\n onPause?: () => void;\n onEnded?: () => void;\n onTimeUpdate?: (time: number) => void;\n onError?: (error: Error) => void;\n onReady?: () => void;\n}\n\nexport interface HybridAudioState {\n isReady: boolean;\n isPlaying: boolean;\n currentTime: number;\n duration: number;\n volume: number;\n isMuted: boolean;\n isLooping: boolean;\n buffered: TimeRanges | null;\n error: Error | null;\n}\n\nexport interface HybridAudioControls {\n play: () => Promise<void>;\n pause: () => void;\n togglePlay: () => void;\n seek: (time: number) => void;\n seekTo: (progress: number) => void;\n skip: (seconds: number) => void;\n setVolume: (vol: number) => void;\n toggleMute: () => void;\n toggleLoop: () => void;\n setLoop: (enabled: boolean) => void;\n restart: () => void;\n}\n\nexport interface HybridWebAudioAPI {\n context: AudioContext | null;\n analyser: AnalyserNode | null;\n sourceNode: MediaElementAudioSourceNode | null;\n}\n\nexport interface UseHybridAudioReturn {\n audioRef: React.RefObject<HTMLAudioElement | null>;\n state: HybridAudioState;\n controls: HybridAudioControls;\n webAudio: HybridWebAudioAPI;\n}\n\n// =============================================================================\n// HOOK\n// =============================================================================\n\nexport function useHybridAudio(options: UseHybridAudioOptions): UseHybridAudioReturn {\n const {\n src,\n autoPlay = false,\n initialVolume = 1,\n loop = false,\n crossOrigin = 'anonymous',\n excludeFromBus = false,\n onPlay,\n onPause,\n onEnded,\n onTimeUpdate,\n onError,\n onReady,\n } = options;\n\n const playerId = useId();\n\n // Refs\n const audioRef = useRef<HTMLAudioElement | null>(null);\n const audioContextRef = useRef<AudioContext | null>(null);\n const sourceNodeRef = useRef<MediaElementAudioSourceNode | null>(null);\n const analyserRef = useRef<AnalyserNode | null>(null);\n const connectedElementRef = useRef<HTMLMediaElement | null>(null);\n\n // State\n const [state, setState] = useState<HybridAudioState>({\n isReady: false,\n isPlaying: false,\n currentTime: 0,\n duration: 0,\n volume: initialVolume,\n isMuted: false,\n isLooping: loop,\n buffered: null,\n error: null,\n });\n\n // Initialize Web Audio for visualization (lazy, on first play)\n const initWebAudio = useCallback(() => {\n const audio = audioRef.current;\n if (!audio) return;\n\n // Already connected to this element\n if (connectedElementRef.current === audio && audioContextRef.current) {\n return;\n }\n\n try {\n // Create AudioContext if needed\n if (!audioContextRef.current) {\n const AudioContextClass =\n window.AudioContext ||\n (window as unknown as { webkitAudioContext: typeof AudioContext }).webkitAudioContext;\n audioContextRef.current = new AudioContextClass();\n }\n\n const ctx = audioContextRef.current;\n\n // Disconnect old source if any\n if (sourceNodeRef.current) {\n try {\n sourceNodeRef.current.disconnect();\n } catch {\n /* ignore */\n }\n }\n\n // Create source from audio element\n const source = ctx.createMediaElementSource(audio);\n sourceNodeRef.current = source;\n\n // Create analyser for visualization\n const analyser = ctx.createAnalyser();\n analyser.fftSize = 256;\n analyser.smoothingTimeConstant = 0.85;\n analyserRef.current = analyser;\n\n // Audio routing:\n // 1. source -> destination (for playback)\n // 2. source -> analyser (for visualization only - NO output!)\n source.connect(ctx.destination);\n source.connect(analyser);\n // NOTE: analyser does NOT connect to destination - prevents double audio!\n\n connectedElementRef.current = audio;\n } catch (error) {\n console.warn('[useHybridAudio] Web Audio init failed:', error);\n }\n }, []);\n\n // Audio bus — stop other players when this one plays\n const { announce: busAnnounce, release: busRelease } = useAudioBus(\n playerId,\n useCallback(() => {\n if (!excludeFromBus) audioRef.current?.pause();\n }, [excludeFromBus])\n );\n\n // Resume AudioContext on user interaction\n const resumeAudioContext = useCallback(async () => {\n const ctx = audioContextRef.current;\n if (ctx && ctx.state === 'suspended') {\n await ctx.resume();\n }\n }, []);\n\n // Controls\n const play = useCallback(async () => {\n const audio = audioRef.current;\n if (!audio) return;\n\n try {\n if (!excludeFromBus) busAnnounce();\n initWebAudio();\n await resumeAudioContext();\n await audio.play();\n } catch (error) {\n console.error('[useHybridAudio] Play failed:', error);\n onError?.(error as Error);\n }\n }, [excludeFromBus, busAnnounce, initWebAudio, resumeAudioContext, onError]);\n\n const pause = useCallback(() => {\n audioRef.current?.pause();\n }, []);\n\n const togglePlay = useCallback(() => {\n if (state.isPlaying) {\n pause();\n } else {\n play();\n }\n }, [state.isPlaying, play, pause]);\n\n const seek = useCallback(\n (time: number) => {\n const audio = audioRef.current;\n if (audio && isFinite(time)) {\n audio.currentTime = Math.max(0, Math.min(time, state.duration || audio.duration || 0));\n }\n },\n [state.duration]\n );\n\n const seekTo = useCallback(\n (progress: number) => {\n const duration = state.duration || audioRef.current?.duration || 0;\n seek(duration * Math.max(0, Math.min(1, progress)));\n },\n [state.duration, seek]\n );\n\n const skip = useCallback(\n (seconds: number) => {\n seek(state.currentTime + seconds);\n },\n [state.currentTime, seek]\n );\n\n const setVolume = useCallback((vol: number) => {\n const audio = audioRef.current;\n if (audio) {\n const clampedVol = Math.max(0, Math.min(1, vol));\n audio.volume = clampedVol;\n setState((prev) => ({ ...prev, volume: clampedVol }));\n }\n }, []);\n\n const toggleMute = useCallback(() => {\n const audio = audioRef.current;\n if (audio) {\n audio.muted = !audio.muted;\n setState((prev) => ({ ...prev, isMuted: audio.muted }));\n }\n }, []);\n\n const toggleLoop = useCallback(() => {\n const audio = audioRef.current;\n if (audio) {\n audio.loop = !audio.loop;\n setState((prev) => ({ ...prev, isLooping: audio.loop }));\n }\n }, []);\n\n const setLoop = useCallback((enabled: boolean) => {\n const audio = audioRef.current;\n if (audio) {\n audio.loop = enabled;\n setState((prev) => ({ ...prev, isLooping: enabled }));\n }\n }, []);\n\n const restart = useCallback(() => {\n seek(0);\n play();\n }, [seek, play]);\n\n const controls: HybridAudioControls = {\n play,\n pause,\n togglePlay,\n seek,\n seekTo,\n skip,\n setVolume,\n toggleMute,\n toggleLoop,\n setLoop,\n restart,\n };\n\n // Create audio element on mount\n useEffect(() => {\n const audio = document.createElement('audio');\n audio.preload = 'metadata';\n audio.crossOrigin = crossOrigin;\n audio.volume = initialVolume;\n audio.loop = loop;\n audioRef.current = audio;\n\n return () => {\n audio.pause();\n audio.src = '';\n busRelease();\n if (audioContextRef.current) {\n audioContextRef.current.close().catch(() => {});\n }\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n // Event handlers\n useEffect(() => {\n const audio = audioRef.current;\n if (!audio) return;\n\n const handlers = {\n loadedmetadata: () => {\n setState((prev) => ({\n ...prev,\n duration: audio.duration,\n isReady: true,\n }));\n onReady?.();\n },\n canplay: () => {\n setState((prev) => ({ ...prev, isReady: true }));\n if (autoPlay) {\n play();\n }\n },\n play: () => {\n setState((prev) => ({ ...prev, isPlaying: true }));\n onPlay?.();\n },\n pause: () => {\n setState((prev) => ({ ...prev, isPlaying: false }));\n onPause?.();\n },\n ended: () => {\n setState((prev) => ({ ...prev, isPlaying: false }));\n onEnded?.();\n },\n timeupdate: () => {\n setState((prev) => ({ ...prev, currentTime: audio.currentTime }));\n onTimeUpdate?.(audio.currentTime);\n },\n progress: () => {\n setState((prev) => ({ ...prev, buffered: audio.buffered }));\n },\n error: () => {\n const error = new Error(audio.error?.message || 'Audio error');\n setState((prev) => ({ ...prev, error }));\n onError?.(error);\n },\n volumechange: () => {\n setState((prev) => ({\n ...prev,\n volume: audio.volume,\n isMuted: audio.muted,\n }));\n },\n };\n\n Object.entries(handlers).forEach(([event, handler]) => {\n audio.addEventListener(event, handler);\n });\n\n return () => {\n Object.entries(handlers).forEach(([event, handler]) => {\n audio.removeEventListener(event, handler);\n });\n };\n }, [autoPlay, onPlay, onPause, onEnded, onTimeUpdate, onError, onReady, play]);\n\n // Load new source\n useEffect(() => {\n const audio = audioRef.current;\n if (!audio || !src) return;\n\n setState((prev) => ({\n ...prev,\n isReady: false,\n currentTime: 0,\n duration: 0,\n error: null,\n }));\n\n audio.src = src;\n audio.load();\n }, [src]);\n\n return {\n audioRef,\n state,\n controls,\n webAudio: {\n context: audioContextRef.current,\n analyser: analyserRef.current,\n sourceNode: sourceNodeRef.current,\n },\n };\n}\n","'use client';\n\n/**\n * useHybridAudioAnalysis - Audio frequency analysis for hybrid player.\n *\n * Simplified version of useAudioAnalysis that works directly with AnalyserNode\n * instead of SharedWebAudioContext.\n */\n\nimport { useCallback, useEffect, useRef, useState } from 'react';\n\nimport type { AudioLevels } from '../effects';\n\nexport function useHybridAudioAnalysis(\n analyser: AnalyserNode | null,\n isPlaying: boolean\n): AudioLevels {\n const [levels, setLevels] = useState<AudioLevels>({ bass: 0, mid: 0, high: 0, overall: 0 });\n const animationRef = useRef<number | null>(null);\n const dataArrayRef = useRef<Uint8Array<ArrayBuffer> | null>(null);\n\n const cleanup = useCallback(() => {\n if (animationRef.current) {\n cancelAnimationFrame(animationRef.current);\n animationRef.current = null;\n }\n }, []);\n\n // Initialize data array when analyser is available\n useEffect(() => {\n if (analyser && !dataArrayRef.current) {\n dataArrayRef.current = new Uint8Array(analyser.frequencyBinCount) as Uint8Array<ArrayBuffer>;\n }\n }, [analyser]);\n\n // Animation loop\n useEffect(() => {\n if (!isPlaying || !analyser || !dataArrayRef.current) {\n cleanup();\n // Smooth fade out when stopped\n setLevels((prev) => ({\n bass: prev.bass * 0.95 < 0.01 ? 0 : prev.bass * 0.95,\n mid: prev.mid * 0.95 < 0.01 ? 0 : prev.mid * 0.95,\n high: prev.high * 0.95 < 0.01 ? 0 : prev.high * 0.95,\n overall: prev.overall * 0.95 < 0.01 ? 0 : prev.overall * 0.95,\n }));\n return;\n }\n\n const dataArray = dataArrayRef.current;\n\n const animate = () => {\n analyser.getByteFrequencyData(dataArray);\n const binCount = dataArray.length;\n\n // Bass (0-15% of frequency range)\n const bassEnd = Math.floor(binCount * 0.15);\n let bassSum = 0;\n for (let i = 0; i < bassEnd; i++) bassSum += dataArray[i];\n const bass = bassSum / bassEnd / 255;\n\n // Mids (15-50% of frequency range)\n const midStart = bassEnd;\n const midEnd = Math.floor(binCount * 0.5);\n let midSum = 0;\n for (let i = midStart; i < midEnd; i++) midSum += dataArray[i];\n const mid = midSum / (midEnd - midStart) / 255;\n\n // Highs (50-100% of frequency range)\n const highStart = midEnd;\n let highSum = 0;\n for (let i = highStart; i < binCount; i++) highSum += dataArray[i];\n const high = highSum / (binCount - highStart) / 255;\n\n // Overall\n let totalSum = 0;\n for (let i = 0; i < binCount; i++) totalSum += dataArray[i];\n const overall = totalSum / binCount / 255;\n\n // Smooth with lerp for natural feel\n setLevels((prev) => ({\n bass: prev.bass * 0.7 + bass * 0.3,\n mid: prev.mid * 0.7 + mid * 0.3,\n high: prev.high * 0.7 + high * 0.3,\n overall: prev.overall * 0.7 + overall * 0.3,\n }));\n\n animationRef.current = requestAnimationFrame(animate);\n };\n\n animationRef.current = requestAnimationFrame(animate);\n return cleanup;\n }, [analyser, isPlaying, cleanup]);\n\n return levels;\n}\n","'use client';\n\n/**\n * useVisualization - Hook for managing audio visualization settings\n *\n * Persists settings in localStorage for user preferences\n * Uses React Context for shared state between components\n */\n\nimport { createContext, useContext, useCallback, useMemo, type ReactNode } from 'react';\nimport { useLocalStorage } from '../../_shared';\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport type VisualizationVariant = 'glow' | 'orbs' | 'spotlight' | 'mesh' | 'none';\nexport type VisualizationIntensity = 'subtle' | 'medium' | 'strong';\nexport type VisualizationColorScheme = 'primary' | 'vibrant' | 'cool' | 'warm';\n\nexport interface VisualizationSettings {\n /** Enable reactive cover animation */\n enabled: boolean;\n /** Visual effect variant */\n variant: VisualizationVariant;\n /** Effect intensity */\n intensity: VisualizationIntensity;\n /** Color scheme */\n colorScheme: VisualizationColorScheme;\n /** Playback volume (0-1) */\n volume: number;\n /** Loop playback */\n isLooping: boolean;\n}\n\nexport interface UseVisualizationReturn {\n /** Current settings */\n settings: VisualizationSettings;\n /** Toggle visualization on/off */\n toggle: () => void;\n /** Set specific setting */\n setSetting: <K extends keyof VisualizationSettings>(\n key: K,\n value: VisualizationSettings[K]\n ) => void;\n /** Cycle to next variant */\n nextVariant: () => void;\n /** Cycle to next intensity */\n nextIntensity: () => void;\n /** Cycle to next color scheme */\n nextColorScheme: () => void;\n /** Reset to defaults */\n reset: () => void;\n}\n\n// Backward compatibility alias\nexport type UseAudioVisualizationReturn = UseVisualizationReturn;\n\n// =============================================================================\n// CONSTANTS\n// =============================================================================\n\nconst STORAGE_KEY = 'audio-player-settings';\n\nconst DEFAULT_SETTINGS: VisualizationSettings = {\n enabled: true,\n variant: 'spotlight',\n intensity: 'medium',\n colorScheme: 'primary',\n volume: 1,\n isLooping: false,\n};\n\nconst VARIANTS: VisualizationVariant[] = ['spotlight', 'glow', 'orbs', 'mesh', 'none'];\nconst INTENSITIES: VisualizationIntensity[] = ['subtle', 'medium', 'strong'];\nconst COLOR_SCHEMES: VisualizationColorScheme[] = ['primary', 'vibrant', 'cool', 'warm'];\n\n// =============================================================================\n// CONTEXT\n// =============================================================================\n\nconst VisualizationContext = createContext<UseVisualizationReturn | null>(null);\n\n// =============================================================================\n// PROVIDER\n// =============================================================================\n\nexport interface VisualizationProviderProps {\n children: ReactNode;\n}\n\nexport function VisualizationProvider({ children }: VisualizationProviderProps) {\n const value = useVisualizationState();\n return (\n <VisualizationContext.Provider value={value}>\n {children}\n </VisualizationContext.Provider>\n );\n}\n\n// =============================================================================\n// INTERNAL HOOK (creates the actual state)\n// =============================================================================\n\nfunction useVisualizationState(): UseVisualizationReturn {\n const [settings, setSettings] = useLocalStorage<VisualizationSettings>(\n STORAGE_KEY,\n DEFAULT_SETTINGS\n );\n\n const toggle = useCallback(() => {\n setSettings((prev) => ({ ...prev, enabled: !prev.enabled }));\n }, [setSettings]);\n\n const setSetting = useCallback(\n <K extends keyof VisualizationSettings>(\n key: K,\n value: VisualizationSettings[K]\n ) => {\n setSettings((prev) => ({ ...prev, [key]: value }));\n },\n [setSettings]\n );\n\n const nextVariant = useCallback(() => {\n setSettings((prev) => {\n const currentIndex = VARIANTS.indexOf(prev.variant);\n const nextIndex = (currentIndex + 1) % VARIANTS.length;\n return { ...prev, variant: VARIANTS[nextIndex] };\n });\n }, [setSettings]);\n\n const nextIntensity = useCallback(() => {\n setSettings((prev) => {\n const currentIndex = INTENSITIES.indexOf(prev.intensity);\n const nextIndex = (currentIndex + 1) % INTENSITIES.length;\n return { ...prev, intensity: INTENSITIES[nextIndex] };\n });\n }, [setSettings]);\n\n const nextColorScheme = useCallback(() => {\n setSettings((prev) => {\n const currentIndex = COLOR_SCHEMES.indexOf(prev.colorScheme);\n const nextIndex = (currentIndex + 1) % COLOR_SCHEMES.length;\n return { ...prev, colorScheme: COLOR_SCHEMES[nextIndex] };\n });\n }, [setSettings]);\n\n const reset = useCallback(() => {\n setSettings(DEFAULT_SETTINGS);\n }, [setSettings]);\n\n return useMemo(\n () => ({\n settings,\n toggle,\n setSetting,\n nextVariant,\n nextIntensity,\n nextColorScheme,\n reset,\n }),\n [settings, toggle, setSetting, nextVariant, nextIntensity, nextColorScheme, reset]\n );\n}\n\n// =============================================================================\n// HOOK (uses context when available)\n// =============================================================================\n\nexport function useVisualization(): UseVisualizationReturn {\n const context = useContext(VisualizationContext);\n\n // Always call the fallback hooks (React hooks rules require consistent calls)\n const fallbackState = useVisualizationState();\n\n // If inside a provider, use shared context; otherwise use fallback\n return context ?? fallbackState;\n}\n\n// Backward compatibility alias\nexport const useAudioVisualization = useVisualization;\n\n// =============================================================================\n// VARIANT INFO\n// =============================================================================\n\nexport const VARIANT_INFO: Record<VisualizationVariant, { label: string; icon: string }> = {\n spotlight: { label: 'Spotlight', icon: '💫' },\n glow: { label: 'Glow', icon: '✨' },\n orbs: { label: 'Orbs', icon: '🔮' },\n mesh: { label: 'Mesh', icon: '🌈' },\n none: { label: 'Off', icon: '⭕' },\n};\n\nexport const INTENSITY_INFO: Record<VisualizationIntensity, { label: string }> = {\n subtle: { label: 'Subtle' },\n medium: { label: 'Medium' },\n strong: { label: 'Strong' },\n};\n\nexport const COLOR_SCHEME_INFO: Record<VisualizationColorScheme, { label: string; preview: string }> = {\n primary: { label: 'Primary', preview: '🔵' },\n vibrant: { label: 'Vibrant', preview: '🌈' },\n cool: { label: 'Cool', preview: '💙' },\n warm: { label: 'Warm', preview: '🔥' },\n};\n","'use client';\n\n/**\n * HybridAudioProvider - Context provider for hybrid audio player.\n *\n * Provides audio state, controls, and analysis data to child components.\n * Uses native HTML5 audio for playback with Web Audio API for visualization only.\n */\n\nimport { createContext, useContext, useMemo, useEffect, useRef, type ReactNode } from 'react';\nimport {\n useHybridAudio,\n type UseHybridAudioOptions,\n type HybridAudioState,\n type HybridAudioControls,\n type HybridWebAudioAPI,\n} from '../hooks/useHybridAudio';\nimport { useHybridAudioAnalysis } from '../hooks/useHybridAudioAnalysis';\nimport { useVisualization } from '../hooks/useVisualization';\nimport type { AudioLevels } from '../effects';\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport interface HybridAudioContextValue {\n // Audio state\n state: HybridAudioState;\n\n // Controls\n controls: HybridAudioControls;\n\n // Web Audio (for visualizations)\n webAudio: HybridWebAudioAPI;\n\n // Audio levels (for reactive effects)\n audioLevels: AudioLevels;\n\n // Audio element ref (for custom integrations)\n audioRef: React.RefObject<HTMLAudioElement | null>;\n}\n\n// =============================================================================\n// CONTEXT\n// =============================================================================\n\nconst HybridAudioContext = createContext<HybridAudioContextValue | null>(null);\n\n// =============================================================================\n// PROVIDER\n// =============================================================================\n\nexport interface HybridAudioProviderProps extends UseHybridAudioOptions {\n children: ReactNode;\n}\n\nexport function HybridAudioProvider({ children, ...options }: HybridAudioProviderProps) {\n // Load persisted settings (shared with visualization)\n const { settings: savedSettings, setSetting } = useVisualization();\n\n // Use saved settings as initial values\n const effectiveOptions = {\n ...options,\n initialVolume: savedSettings.volume,\n loop: savedSettings.isLooping,\n };\n\n const { audioRef, state, controls, webAudio } = useHybridAudio(effectiveOptions);\n\n // Track if we've applied initial settings\n const hasAppliedInitialSettings = useRef(false);\n\n // Apply saved settings after audio is ready (for hydration timing)\n useEffect(() => {\n if (!state.isReady || hasAppliedInitialSettings.current) return;\n hasAppliedInitialSettings.current = true;\n\n // Apply saved volume and loop settings\n controls.setVolume(savedSettings.volume);\n controls.setLoop(savedSettings.isLooping);\n }, [state.isReady, savedSettings, controls]);\n\n // Persist settings when they change\n useEffect(() => {\n if (!state.isReady) return;\n\n // Only save if values actually changed\n if (state.volume !== savedSettings.volume) {\n setSetting('volume', state.volume);\n }\n if (state.isLooping !== savedSettings.isLooping) {\n setSetting('isLooping', state.isLooping);\n }\n }, [state.isReady, state.volume, state.isLooping, savedSettings, setSetting]);\n\n // Audio analysis for reactive effects\n const audioLevels = useHybridAudioAnalysis(webAudio.analyser, state.isPlaying);\n\n const value = useMemo<HybridAudioContextValue>(\n () => ({\n state,\n controls,\n webAudio,\n audioLevels,\n audioRef,\n }),\n [state, controls, webAudio, audioLevels, audioRef]\n );\n\n return <HybridAudioContext.Provider value={value}>{children}</HybridAudioContext.Provider>;\n}\n\n// =============================================================================\n// HOOKS\n// =============================================================================\n\n/**\n * Access full hybrid audio context\n */\nexport function useHybridAudioContext(): HybridAudioContextValue {\n const context = useContext(HybridAudioContext);\n if (!context) {\n throw new Error('useHybridAudioContext must be used within HybridAudioProvider');\n }\n return context;\n}\n\n/**\n * Access audio state only (read-only)\n */\nexport function useHybridAudioState(): HybridAudioState {\n const { state } = useHybridAudioContext();\n return state;\n}\n\n/**\n * Access audio controls only (no state re-renders)\n */\nexport function useHybridAudioControls(): HybridAudioControls {\n const { controls } = useHybridAudioContext();\n return controls;\n}\n\n/**\n * Access audio levels for reactive effects\n */\nexport function useHybridAudioLevels(): AudioLevels {\n const { audioLevels } = useHybridAudioContext();\n return audioLevels;\n}\n\n/**\n * Access Web Audio API for custom visualizations\n */\nexport function useHybridWebAudio(): HybridWebAudioAPI {\n const { webAudio } = useHybridAudioContext();\n return webAudio;\n}\n","'use client';\n\n/**\n * HybridWaveform - Real-time frequency visualization for hybrid player.\n *\n * Two modes:\n * - 'frequency': Real-time frequency bars (default, requires playing audio)\n * - 'static': Static progress bar (for when no analyser is available)\n *\n * Features:\n * - Shows buffered regions\n * - Click to seek\n * - Responsive width\n */\n\nimport { useRef, useEffect, useCallback, memo } from 'react';\nimport { useHybridAudioContext } from '../context/HybridAudioProvider';\nimport { cn } from '@djangocfg/ui-core/lib';\nimport { useThemeColor } from '@djangocfg/ui-core/styles/palette';\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport interface HybridWaveformProps {\n /** Visualization mode */\n mode?: 'frequency' | 'static';\n /** Canvas height in pixels */\n height?: number;\n /** Bar width in pixels */\n barWidth?: number;\n /** Gap between bars in pixels */\n barGap?: number;\n /** Bar border radius */\n barRadius?: number;\n /** Color for played portion */\n progressColor?: string;\n /** Color for unplayed portion */\n waveColor?: string;\n /** Color for buffered regions indicator */\n bufferedColor?: string;\n /** Additional CSS class */\n className?: string;\n /** Callback when user seeks */\n onSeek?: (time: number) => void;\n}\n\n// =============================================================================\n// COMPONENT\n// =============================================================================\n\nexport const HybridWaveform = memo(function HybridWaveform({\n mode = 'frequency',\n height = 64,\n barWidth = 3,\n barGap = 2,\n barRadius = 2,\n progressColor,\n waveColor,\n bufferedColor,\n className,\n onSeek,\n}: HybridWaveformProps) {\n const themePrimary = useThemeColor('primary');\n const themePrimaryWave = useThemeColor('primary', 0.3);\n const themePrimaryBuffered = useThemeColor('primary', 0.15);\n const resolvedProgressColor = progressColor ?? themePrimary;\n const resolvedWaveColor = waveColor ?? themePrimaryWave;\n const resolvedBufferedColor = bufferedColor ?? themePrimaryBuffered;\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n const animationRef = useRef<number | null>(null);\n const { state, controls, webAudio } = useHybridAudioContext();\n\n // Handle click to seek\n const handleClick = useCallback(\n (e: React.MouseEvent<HTMLCanvasElement>) => {\n const canvas = canvasRef.current;\n if (!canvas || !state.duration) return;\n\n const rect = canvas.getBoundingClientRect();\n const x = e.clientX - rect.left;\n const progress = x / rect.width;\n const time = state.duration * progress;\n\n controls.seek(time);\n onSeek?.(time);\n },\n [state.duration, controls, onSeek]\n );\n\n // Render frequency bars (real-time visualization)\n const renderFrequency = useCallback(() => {\n const canvas = canvasRef.current;\n const analyser = webAudio.analyser;\n if (!canvas) return;\n\n const ctx = canvas.getContext('2d');\n if (!ctx) return;\n\n const { width, height: canvasHeight } = canvas;\n const dpr = window.devicePixelRatio || 1;\n const displayWidth = width / dpr;\n\n // Get frequency data if analyser is available\n let dataArray: Uint8Array<ArrayBuffer> | null = null;\n if (analyser) {\n dataArray = new Uint8Array(analyser.frequencyBinCount) as Uint8Array<ArrayBuffer>;\n analyser.getByteFrequencyData(dataArray);\n }\n\n ctx.clearRect(0, 0, width, canvasHeight);\n\n // Draw buffered regions at bottom\n if (state.buffered && state.duration > 0) {\n ctx.fillStyle = resolvedBufferedColor;\n for (let i = 0; i < state.buffered.length; i++) {\n const start = (state.buffered.start(i) / state.duration) * width;\n const end = (state.buffered.end(i) / state.duration) * width;\n ctx.fillRect(start, canvasHeight - 3 * dpr, end - start, 3 * dpr);\n }\n }\n\n // Calculate bar count based on available width\n const barCount = Math.floor(displayWidth / (barWidth + barGap));\n const progress = state.duration > 0 ? state.currentTime / state.duration : 0;\n const progressX = width * progress;\n\n // Draw bars\n for (let i = 0; i < barCount; i++) {\n let barHeight: number;\n\n if (dataArray && state.isPlaying) {\n // Real-time frequency data\n const step = Math.floor(dataArray.length / barCount);\n const value = dataArray[i * step] / 255;\n barHeight = Math.max(4 * dpr, value * (canvasHeight - 6 * dpr) * 0.9);\n } else {\n // Static fallback - small bars\n barHeight = 8 * dpr;\n }\n\n const x = i * (barWidth + barGap) * dpr;\n const y = (canvasHeight - barHeight) / 2;\n\n ctx.fillStyle = x < progressX ? resolvedProgressColor : resolvedWaveColor;\n\n // Draw rounded rect\n const radius = barRadius * dpr;\n const rectWidth = barWidth * dpr;\n ctx.beginPath();\n ctx.roundRect(x, y, rectWidth, barHeight, radius);\n ctx.fill();\n }\n\n // Continue animation if playing\n if (state.isPlaying) {\n animationRef.current = requestAnimationFrame(renderFrequency);\n }\n }, [\n webAudio.analyser,\n state.buffered,\n state.duration,\n state.currentTime,\n state.isPlaying,\n barWidth,\n barGap,\n barRadius,\n resolvedProgressColor,\n resolvedWaveColor,\n resolvedBufferedColor,\n ]);\n\n // Render static progress bar\n const renderStatic = useCallback(() => {\n const canvas = canvasRef.current;\n if (!canvas) return;\n\n const ctx = canvas.getContext('2d');\n if (!ctx) return;\n\n const { width, height: canvasHeight } = canvas;\n const dpr = window.devicePixelRatio || 1;\n\n ctx.clearRect(0, 0, width, canvasHeight);\n\n // Draw buffered regions\n if (state.buffered && state.duration > 0) {\n ctx.fillStyle = resolvedBufferedColor;\n for (let i = 0; i < state.buffered.length; i++) {\n const start = (state.buffered.start(i) / state.duration) * width;\n const end = (state.buffered.end(i) / state.duration) * width;\n ctx.fillRect(start, 0, end - start, canvasHeight);\n }\n }\n\n // Draw progress bar\n const progress = state.duration > 0 ? state.currentTime / state.duration : 0;\n const progressWidth = width * progress;\n\n // Background\n ctx.fillStyle = resolvedWaveColor;\n ctx.fillRect(0, canvasHeight / 2 - 2 * dpr, width, 4 * dpr);\n\n // Progress\n ctx.fillStyle = resolvedProgressColor;\n ctx.fillRect(0, canvasHeight / 2 - 2 * dpr, progressWidth, 4 * dpr);\n\n // Handle\n if (progress > 0) {\n ctx.beginPath();\n ctx.arc(progressWidth, canvasHeight / 2, 6 * dpr, 0, Math.PI * 2);\n ctx.fill();\n }\n }, [state.buffered, state.duration, state.currentTime, resolvedProgressColor, resolvedWaveColor, resolvedBufferedColor]);\n\n // Resize canvas to match container\n useEffect(() => {\n const container = containerRef.current;\n const canvas = canvasRef.current;\n if (!container || !canvas) return;\n\n const resizeObserver = new ResizeObserver((entries) => {\n const entry = entries[0];\n if (!entry) return;\n\n const dpr = window.devicePixelRatio || 1;\n const displayWidth = entry.contentRect.width;\n const displayHeight = height;\n\n canvas.width = displayWidth * dpr;\n canvas.height = displayHeight * dpr;\n canvas.style.width = `${displayWidth}px`;\n canvas.style.height = `${displayHeight}px`;\n\n // Re-render after resize\n if (mode === 'frequency') {\n renderFrequency();\n } else {\n renderStatic();\n }\n });\n\n resizeObserver.observe(container);\n return () => resizeObserver.disconnect();\n }, [height, mode, renderFrequency, renderStatic]);\n\n // Animation loop for frequency mode\n useEffect(() => {\n if (mode === 'frequency') {\n renderFrequency();\n }\n\n return () => {\n if (animationRef.current) {\n cancelAnimationFrame(animationRef.current);\n }\n };\n }, [mode, renderFrequency]);\n\n // Re-render on time change for static mode\n useEffect(() => {\n if (mode === 'static') {\n renderStatic();\n }\n }, [mode, state.currentTime, renderStatic]);\n\n // Re-render frequency when playback state changes\n useEffect(() => {\n if (mode === 'frequency' && !state.isPlaying) {\n // One final render when stopped\n renderFrequency();\n }\n }, [mode, state.isPlaying, renderFrequency]);\n\n return (\n <div ref={containerRef} className={cn('w-full', className)}>\n <canvas\n ref={canvasRef}\n onClick={handleClick}\n className=\"cursor-pointer\"\n style={{ width: '100%', height }}\n />\n </div>\n );\n});\n","/**\n * formatTime - Format seconds to mm:ss string\n */\n\nexport function formatTime(seconds: number): string {\n if (!seconds || !isFinite(seconds) || seconds < 0) return '0:00';\n const mins = Math.floor(seconds / 60);\n const secs = Math.floor(seconds % 60);\n return `${mins}:${secs.toString().padStart(2, '0')}`;\n}\n","'use client';\n\n/**\n * AudioPlayer Debug Logger\n *\n * Uses universal logger with media-specific helpers.\n * Logs go to both console (dev) and zustand store (for Console panel).\n */\n\nimport { createMediaLogger } from '@djangocfg/ui-core/lib';\n\nexport const audioDebug = createMediaLogger('AudioPlayer');\n\nexport default audioDebug;\n","'use client';\n\n/**\n * HybridAudioPlayer - Audio playback controls with frequency visualization\n *\n * Uses HybridAudioContext for state management.\n * Native HTML5 audio for playback, Web Audio API for visualization only.\n *\n * Features:\n * - Real-time frequency visualization\n * - Playback controls (play, pause, skip, restart)\n * - Volume control with mute\n * - Loop toggle\n * - Keyboard shortcuts\n * - Timer display\n */\n\nimport { memo, useMemo } from 'react';\nimport {\n Play,\n Pause,\n RotateCcw,\n SkipBack,\n SkipForward,\n Volume2,\n VolumeX,\n Loader2,\n Repeat,\n} from 'lucide-react';\nimport { useTypedT, type I18nTranslations } from '@djangocfg/i18n';\nimport { Button, Slider, cn } from '../../_shared';\nimport { useHybridAudioContext } from '../context/HybridAudioProvider';\nimport { HybridWaveform } from './HybridWaveform';\nimport { formatTime } from '../utils';\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport interface HybridAudioPlayerProps {\n /** Show playback controls */\n showControls?: boolean;\n /** Show frequency waveform */\n showWaveform?: boolean;\n /** Waveform visualization mode */\n waveformMode?: 'frequency' | 'static';\n /** Waveform height in pixels */\n waveformHeight?: number;\n /** Show time display */\n showTimer?: boolean;\n /** Show volume control */\n showVolume?: boolean;\n /** Show loop button */\n showLoop?: boolean;\n /** Additional CSS class */\n className?: string;\n /** Inline styles */\n style?: React.CSSProperties;\n}\n\n// =============================================================================\n// COMPONENT\n// =============================================================================\n\nexport const HybridAudioPlayer = memo(function HybridAudioPlayer({\n showControls = true,\n showWaveform = true,\n waveformMode = 'frequency',\n waveformHeight = 64,\n showTimer = true,\n showVolume = true,\n showLoop = true,\n className,\n style,\n}: HybridAudioPlayerProps) {\n const t = useTypedT<I18nTranslations>();\n const { state, controls } = useHybridAudioContext();\n\n const labels = useMemo(() => ({\n restart: t('tools.audio.restart'),\n back: t('tools.audio.back'),\n forward: t('tools.audio.forward'),\n volume: t('tools.audio.volume'),\n }), [t]);\n\n const isLoading = !state.isReady;\n\n const handleVolumeChange = (value: number[]) => {\n controls.setVolume(value[0] / 100);\n };\n\n return (\n <div\n className={cn('flex flex-col gap-3 p-4 rounded-lg bg-card border', className)}\n style={style}\n >\n {/* Frequency Waveform */}\n {showWaveform && (\n <div className=\"relative\">\n <HybridWaveform\n mode={waveformMode}\n height={waveformHeight}\n className={cn(isLoading && 'opacity-50')}\n />\n {isLoading && (\n <div className=\"absolute inset-0 flex items-center justify-center\">\n <Loader2 className=\"h-6 w-6 animate-spin text-primary\" />\n </div>\n )}\n </div>\n )}\n\n {/* Timer */}\n {showTimer && (\n <div className=\"flex justify-between text-xs text-muted-foreground tabular-nums px-1\">\n <span>{formatTime(state.currentTime)}</span>\n <span>{formatTime(state.duration)}</span>\n </div>\n )}\n\n {/* Controls */}\n {showControls && (\n <div className=\"flex items-center justify-center gap-1\">\n {/* Restart */}\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-9 w-9\"\n onClick={controls.restart}\n disabled={!state.isReady}\n title={labels.restart}\n >\n <RotateCcw className=\"h-4 w-4\" />\n </Button>\n\n {/* Skip back 5s */}\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-9 w-9\"\n onClick={() => controls.skip(-5)}\n disabled={!state.isReady}\n title={labels.back}\n >\n <SkipBack className=\"h-4 w-4\" />\n </Button>\n\n {/* Play/Pause */}\n <Button\n variant=\"default\"\n size=\"icon\"\n className=\"h-12 w-12 rounded-full\"\n onClick={controls.togglePlay}\n disabled={!state.isReady && !isLoading}\n title={state.isPlaying ? 'Pause' : 'Play'}\n >\n {isLoading ? (\n <Loader2 className=\"h-5 w-5 animate-spin\" />\n ) : state.isPlaying ? (\n <Pause className=\"h-5 w-5\" />\n ) : (\n <Play className=\"h-5 w-5 ml-0.5\" />\n )}\n </Button>\n\n {/* Skip forward 5s */}\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-9 w-9\"\n onClick={() => controls.skip(5)}\n disabled={!state.isReady}\n title={labels.forward}\n >\n <SkipForward className=\"h-4 w-4\" />\n </Button>\n\n {/* Volume */}\n {showVolume && (\n <>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-9 w-9\"\n onClick={controls.toggleMute}\n title={state.isMuted ? 'Unmute' : 'Mute'}\n >\n {state.isMuted || state.volume === 0 ? (\n <VolumeX className=\"h-4 w-4\" />\n ) : (\n <Volume2 className=\"h-4 w-4\" />\n )}\n </Button>\n\n <Slider\n value={[state.isMuted ? 0 : state.volume * 100]}\n max={100}\n step={1}\n onValueChange={handleVolumeChange}\n className=\"w-20\"\n aria-label={labels.volume}\n />\n </>\n )}\n\n {/* Loop/Repeat */}\n {showLoop && (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className={cn('h-9 w-9', state.isLooping && 'text-primary')}\n onClick={controls.toggleLoop}\n disabled={!state.isReady}\n title={state.isLooping ? 'Disable loop' : 'Enable loop'}\n >\n <Repeat className=\"h-4 w-4\" />\n </Button>\n )}\n </div>\n )}\n </div>\n );\n});\n\nexport default HybridAudioPlayer;\n","/**\n * Audio Reactive Effects - Common utilities and types\n *\n * Provides reusable effect calculations and configurations\n */\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport type EffectVariant = 'glow' | 'orbs' | 'spotlight' | 'mesh';\nexport type EffectIntensity = 'subtle' | 'medium' | 'strong';\nexport type EffectColorScheme = 'primary' | 'vibrant' | 'cool' | 'warm';\n\nexport interface AudioLevels {\n bass: number;\n mid: number;\n high: number;\n overall: number;\n}\n\nexport interface EffectConfig {\n opacity: number;\n scale: number;\n blur: string;\n}\n\nexport interface EffectColors {\n colors: string[];\n hueShift: number;\n}\n\nexport interface EffectLayer {\n inset: number;\n opacity: number;\n scale: number;\n background: string;\n blur: string;\n animation?: string;\n}\n\n// =============================================================================\n// CONSTANTS\n// =============================================================================\n\nexport const INTENSITY_CONFIG: Record<EffectIntensity, EffectConfig> = {\n subtle: { opacity: 0.3, scale: 0.02, blur: 'blur-2xl' },\n medium: { opacity: 0.5, scale: 0.04, blur: 'blur-xl' },\n strong: { opacity: 0.7, scale: 0.06, blur: 'blur-lg' },\n};\n\nexport const COLOR_SCHEMES: Record<EffectColorScheme, string[]> = {\n primary: ['217 91% 60%'],\n vibrant: ['217 91% 60%', '142 76% 36%', '262 83% 58%', '25 95% 53%'],\n cool: ['217 91% 60%', '262 83% 58%', '199 89% 48%'],\n warm: ['25 95% 53%', '0 84% 60%', '38 92% 50%'],\n};\n\n// Default multi-color palette when single color provided\nconst DEFAULT_GLOW_COLORS = [\n '217 91% 60%', // Blue\n '262 83% 58%', // Purple\n '330 81% 60%', // Pink\n '25 95% 53%', // Orange\n];\n\n// =============================================================================\n// UTILITIES\n// =============================================================================\n\n/**\n * Get effect configuration from intensity setting\n */\nexport function getEffectConfig(intensity: EffectIntensity): EffectConfig {\n return INTENSITY_CONFIG[intensity];\n}\n\n/**\n * Get color array from color scheme\n */\nexport function getColors(colorScheme: EffectColorScheme): string[] {\n return COLOR_SCHEMES[colorScheme];\n}\n\n/**\n * Prepare colors with hue shift based on audio levels\n */\nexport function prepareEffectColors(\n colorScheme: EffectColorScheme,\n levels: AudioLevels\n): EffectColors {\n const baseColors = COLOR_SCHEMES[colorScheme];\n const colors = baseColors.length > 1 ? baseColors : DEFAULT_GLOW_COLORS;\n const hueShift = Math.floor(\n (levels.bass * 30) + (levels.mid * 20) + (levels.high * 10)\n );\n\n return { colors, hueShift };\n}\n\n/**\n * Calculate glow layer properties\n */\nexport function calculateGlowLayers(\n levels: AudioLevels,\n config: EffectConfig,\n colors: string[]\n): EffectLayer[] {\n const { bass, mid, high } = levels;\n\n return [\n // Layer 1: Bass glow - bottom\n {\n inset: 60 + bass * 90,\n opacity: 1,\n scale: 1 + bass * 0.5,\n background: `radial-gradient(ellipse 80% 60% at 50% 100%, hsl(${colors[0]} / ${0.4 + bass * 0.4}) 0%, transparent 70%)`,\n blur: 'blur-3xl',\n },\n // Layer 2: Mid glow - top\n {\n inset: 45 + mid * 75,\n opacity: 1,\n scale: 1 + mid * 0.4,\n background: `radial-gradient(ellipse 70% 50% at 50% 0%, hsl(${colors[1] || colors[0]} / ${0.3 + mid * 0.5}) 0%, transparent 70%)`,\n blur: 'blur-2xl',\n },\n // Layer 3: High glow - left\n {\n inset: 30 + high * 60,\n opacity: 1,\n scale: 1 + high * 0.3,\n background: `radial-gradient(ellipse 50% 80% at 0% 50%, hsl(${colors[2] || colors[0]} / ${0.3 + high * 0.4}) 0%, transparent 60%)`,\n blur: 'blur-2xl',\n },\n // Layer 4: High glow - right\n {\n inset: 30 + high * 60,\n opacity: 1,\n scale: 1 + high * 0.3,\n background: `radial-gradient(ellipse 50% 80% at 100% 50%, hsl(${colors[3] || colors[0]} / ${0.3 + high * 0.4}) 0%, transparent 60%)`,\n blur: 'blur-2xl',\n },\n // Layer 5: Center pulsing glow\n {\n inset: 24 + bass * 45,\n opacity: 1,\n scale: 1 + bass * 0.2,\n background: `radial-gradient(circle at 50% 50%, hsl(${colors[0]} / ${0.2 + bass * 0.3}) 0%, hsl(${colors[1] || colors[0]} / ${0.1 + mid * 0.2}) 40%, transparent 70%)`,\n blur: 'blur-xl',\n animation: 'glow-breathe 2s ease-in-out infinite',\n },\n ];\n}\n\n/**\n * Calculate orb positions and properties - highly reactive\n */\nexport function calculateOrbs(\n levels: AudioLevels,\n config: EffectConfig,\n colors: string[],\n baseSize: number = 50\n) {\n const { bass, mid, high, overall } = levels;\n const size = baseSize * 3;\n\n // Dynamic position offsets\n const bassMove = bass * 30;\n const midMove = mid * 25;\n const highMove = high * 20;\n\n return [\n // Bass orb - top left, big pulses\n {\n x: -40 + bassMove,\n y: -40 - bassMove * 0.5,\n size: size * (1 + bass * 1.2),\n color: colors[0],\n opacity: 0.5 + bass * 0.5,\n scale: 1 + bass * 0.6,\n },\n // Mid orb - top right\n {\n x: 130 - midMove * 0.5,\n y: -30 + midMove,\n size: size * (0.9 + mid * 1.0),\n color: colors[1] || colors[0],\n opacity: 0.5 + mid * 0.5,\n scale: 1 + mid * 0.5,\n },\n // High orb - bottom right\n {\n x: 140 + highMove * 0.3,\n y: 120 - highMove,\n size: size * (0.8 + high * 0.8),\n color: colors[2] || colors[0],\n opacity: 0.4 + high * 0.6,\n scale: 1 + high * 0.45,\n },\n // Mid orb 2 - bottom left\n {\n x: -30 - midMove * 0.4,\n y: 130 + midMove * 0.3,\n size: size * (0.9 + mid * 0.9),\n color: colors[3] || colors[0],\n opacity: 0.45 + mid * 0.55,\n scale: 1 + mid * 0.5,\n },\n // Center overall orb\n {\n x: 50,\n y: 50,\n size: size * (0.6 + overall * 1.5),\n color: colors[0],\n opacity: 0.3 + overall * 0.5,\n scale: 1 + overall * 0.7,\n },\n ];\n}\n\n/**\n * Calculate mesh gradient positions - dynamic and reactive\n */\nexport function calculateMeshGradients(\n levels: AudioLevels,\n config: EffectConfig,\n colors: string[]\n) {\n const { bass, mid, high, overall } = levels;\n\n // More aggressive offsets for visible movement\n const bassOffset = bass * 40;\n const midOffset = mid * 30;\n const highOffset = high * 25;\n\n return [\n // Large bass blob - top right, pulses hard\n {\n width: `${200 + bass * 150}%`,\n height: `${200 + bass * 150}%`,\n top: `${-80 + bassOffset}%`,\n right: `${-80 - bassOffset}%`,\n color: colors[0],\n opacity: 0.4 + bass * 0.6,\n scale: 1 + bass * 0.5,\n rotation: bass * 45,\n blur: 'blur-2xl',\n },\n // Mid blob - bottom left\n {\n width: `${180 + mid * 120}%`,\n height: `${180 + mid * 120}%`,\n bottom: `${-60 + midOffset}%`,\n left: `${-60 - midOffset}%`,\n color: colors[1] || colors[0],\n opacity: 0.4 + mid * 0.6,\n scale: 1 + mid * 0.4,\n rotation: -mid * 40,\n blur: 'blur-2xl',\n },\n // High blob - bottom right\n {\n width: `${140 + high * 100}%`,\n height: `${140 + high * 100}%`,\n top: `${70 - highOffset}%`,\n right: `${-50 + highOffset}%`,\n color: colors[2] || colors[0],\n opacity: 0.35 + high * 0.65,\n scale: 1 + high * 0.35,\n rotation: high * 35,\n blur: 'blur-xl',\n },\n // Extra bass reactive blob - top left\n {\n width: `${160 + bass * 140}%`,\n height: `${160 + bass * 140}%`,\n top: `${-60 - bassOffset * 0.8}%`,\n left: `${-60 + bassOffset * 0.8}%`,\n color: colors[3] || colors[1] || colors[0],\n opacity: 0.35 + bass * 0.65,\n scale: 1 + bass * 0.55,\n rotation: -bass * 50,\n blur: 'blur-2xl',\n },\n // Center glow - pulses with overall\n {\n width: `${80 + overall * 150}%`,\n height: `${80 + overall * 150}%`,\n top: '50%',\n left: '50%',\n color: colors[0],\n opacity: 0.3 + overall * 0.5,\n scale: 1 + overall * 0.4,\n rotation: 0,\n isCenter: true,\n blur: 'blur-3xl',\n },\n ];\n}\n\n/**\n * Calculate spotlight effect properties - highly reactive\n */\nexport function calculateSpotlight(\n levels: AudioLevels,\n config: EffectConfig,\n colors: string[],\n rotation: number\n) {\n const { bass, mid, high, overall } = levels;\n\n return {\n // Rotation speed increases with mid frequencies\n rotation: rotation + mid * 180,\n // Border expands with bass\n inset: 12 + bass * 30,\n // Color intensities react to different frequencies\n colors: colors.map((c, i) => ({\n color: c,\n opacity: i === 0\n ? 0.3 + bass * 0.7\n : i === 1\n ? 0.3 + mid * 0.7\n : 0.3 + high * 0.7,\n })),\n // Pulse glow - big and reactive\n pulseInset: 24 + bass * 50,\n pulseOpacity: 0.3 + bass * 0.7,\n pulseScale: 1 + bass * 0.4,\n // Extra glow ring\n ringOpacity: 0.2 + overall * 0.6,\n ringScale: 1 + overall * 0.3,\n };\n}\n\n/**\n * CSS for effect animations - can be injected once\n */\nexport const EFFECT_ANIMATIONS = `\n @keyframes spotlight-spin {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n }\n\n @keyframes orb-float-1 {\n 0%, 100% { transform: translate(-50%, -50%) translateY(0); }\n 50% { transform: translate(-50%, -50%) translateY(-15px); }\n }\n\n @keyframes orb-float-2 {\n 0%, 100% { transform: translate(-50%, -50%) translateX(0); }\n 50% { transform: translate(-50%, -50%) translateX(15px); }\n }\n\n @keyframes orb-float-3 {\n 0%, 100% { transform: translate(-50%, -50%) translate(0, 0); }\n 33% { transform: translate(-50%, -50%) translate(10px, -10px); }\n 66% { transform: translate(-50%, -50%) translate(-10px, 10px); }\n }\n\n @keyframes orb-float-4 {\n 0%, 100% { transform: translate(-50%, -50%) translate(0, 0); }\n 50% { transform: translate(-50%, -50%) translate(-15px, -10px); }\n }\n\n @keyframes mesh-float-1 {\n 0%, 100% { transform: translate(0, 0) scale(1); }\n 25% { transform: translate(-5%, 10%) scale(1.05); }\n 50% { transform: translate(5%, 5%) scale(0.95); }\n 75% { transform: translate(-3%, -5%) scale(1.02); }\n }\n\n @keyframes mesh-float-2 {\n 0%, 100% { transform: translate(0, 0) scale(1); }\n 33% { transform: translate(8%, -8%) scale(1.08); }\n 66% { transform: translate(-6%, 6%) scale(0.92); }\n }\n\n @keyframes mesh-float-3 {\n 0%, 100% { transform: translate(0, 0) scale(1); }\n 50% { transform: translate(10%, 10%) scale(1.1); }\n }\n\n @keyframes mesh-float-4 {\n 0%, 100% { transform: translate(0, 0) scale(1) rotate(0deg); }\n 25% { transform: translate(10%, -5%) scale(1.1) rotate(5deg); }\n 50% { transform: translate(-5%, 10%) scale(0.95) rotate(-5deg); }\n 75% { transform: translate(-10%, -10%) scale(1.05) rotate(3deg); }\n }\n\n @keyframes mesh-pulse {\n 0%, 100% { transform: translate(-50%, -50%) scale(1); opacity: 0.3; }\n 50% { transform: translate(-50%, -50%) scale(1.2); opacity: 0.5; }\n }\n\n @keyframes glow-breathe {\n 0%, 100% { opacity: 0.6; transform: scale(1); }\n 50% { opacity: 1; transform: scale(1.05); }\n }\n\n @keyframes glow-rotate {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n }\n\n @keyframes sparkle-move {\n 0% { opacity: 0; transform: scale(0.8); }\n 50% { opacity: 1; }\n 100% { opacity: 0; transform: scale(1.2); }\n }\n`;\n","'use client';\n\n/**\n * GlowEffect - Multi-layer glow effect with pulse rings\n */\n\nimport { cn } from '../../../../_shared';\nimport type { calculateGlowLayers } from '../../../effects';\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport interface GlowEffectData {\n layers: ReturnType<typeof calculateGlowLayers>;\n hueShift: number;\n showPulseRings: boolean;\n showSparkle: boolean;\n}\n\ninterface GlowEffectProps {\n data: GlowEffectData;\n colors: string[];\n isPlaying: boolean;\n}\n\n// =============================================================================\n// COMPONENT\n// =============================================================================\n\nexport function GlowEffect({ data, colors, isPlaying }: GlowEffectProps) {\n const { layers, hueShift, showPulseRings, showSparkle } = data;\n\n return (\n <>\n {/* Main glow layers */}\n {layers.map((layer, i) => (\n <div\n key={i}\n className={cn('absolute rounded-2xl -z-10', layer.blur)}\n style={{\n inset: `-${layer.inset}px`,\n background: layer.background,\n opacity: isPlaying ? layer.opacity : 0,\n transform: i < 2 ? `scaleY(${layer.scale})` : `scale(${layer.scale})`,\n animation: isPlaying && layer.animation ? layer.animation : 'none',\n transition: 'opacity 0.3s',\n }}\n />\n ))}\n\n {/* Rotating color sweep */}\n <div\n className=\"absolute rounded-2xl blur-xl overflow-hidden -z-10\"\n style={{\n inset: '-75px',\n opacity: isPlaying ? 0.6 : 0,\n transition: 'opacity 0.5s',\n }}\n >\n <div\n className=\"absolute inset-0\"\n style={{\n background: `conic-gradient(\n from ${hueShift}deg at 50% 50%,\n hsl(${colors[0]} / 0.4) 0deg,\n hsl(${colors[1] || colors[0]} / 0.3) 90deg,\n hsl(${colors[2] || colors[0]} / 0.3) 180deg,\n hsl(${colors[3] || colors[0]} / 0.3) 270deg,\n hsl(${colors[0]} / 0.4) 360deg\n )`,\n animation: isPlaying ? 'glow-rotate 6s linear infinite' : 'none',\n }}\n />\n </div>\n\n {/* Pulse rings on bass hits */}\n {showPulseRings && (\n <>\n <div\n className=\"absolute -inset-6 rounded-xl border-2 animate-ping -z-10\"\n style={{\n borderColor: `hsl(${colors[0]} / 0.4)`,\n animationDuration: '1s',\n }}\n />\n <div\n className=\"absolute -inset-12 rounded-2xl border animate-ping -z-10\"\n style={{\n borderColor: `hsl(${colors[1] || colors[0]} / 0.3)`,\n animationDuration: '1.5s',\n animationDelay: '0.2s',\n }}\n />\n </>\n )}\n\n {/* Sparkle on high frequencies */}\n {showSparkle && (\n <div\n className=\"absolute -inset-18 rounded-3xl -z-10\"\n style={{\n background: `radial-gradient(circle at 50% 30%, hsl(${colors[2] || colors[0]} / 0.5) 0%, transparent 30%)`,\n animation: 'sparkle-move 0.5s ease-out',\n }}\n />\n )}\n </>\n );\n}\n","'use client';\n\n/**\n * OrbsEffect - Floating orb particles that react to audio\n */\n\nimport { cn } from '../../../../_shared';\nimport type { calculateOrbs } from '../../../effects';\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\ninterface OrbsEffectProps {\n orbs: ReturnType<typeof calculateOrbs>;\n blur: string;\n isPlaying: boolean;\n}\n\n// =============================================================================\n// COMPONENT\n// =============================================================================\n\nexport function OrbsEffect({ orbs, blur, isPlaying }: OrbsEffectProps) {\n return (\n <>\n {orbs.map((orb, i) => (\n <div\n key={i}\n className={cn('absolute rounded-full -z-10', blur)}\n style={{\n width: orb.size,\n height: orb.size,\n left: `${orb.x}%`,\n top: `${orb.y}%`,\n background: `radial-gradient(circle at 30% 30%, hsl(${orb.color}) 0%, hsl(${orb.color} / 0.5) 40%, transparent 70%)`,\n opacity: isPlaying ? orb.opacity : 0,\n transform: `translate(-50%, -50%) scale(${orb.scale})`,\n transition: 'all 0.08s ease-out',\n }}\n />\n ))}\n </>\n );\n}\n","'use client';\n\n/**\n * SpotlightEffect - Rotating spotlight with conic gradients\n */\n\nimport { cn } from '../../../../_shared';\nimport type { calculateSpotlight } from '../../../effects';\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\ninterface SpotlightEffectProps {\n data: ReturnType<typeof calculateSpotlight>;\n colors: string[];\n blur: string;\n isPlaying: boolean;\n}\n\n// =============================================================================\n// COMPONENT\n// =============================================================================\n\nexport function SpotlightEffect({ data, colors, blur, isPlaying }: SpotlightEffectProps) {\n const inset = 'inset' in data ? data.inset : 12;\n const pulseInset = 'pulseInset' in data ? data.pulseInset : 24;\n const ringOpacity = 'ringOpacity' in data ? data.ringOpacity : 0.3;\n const ringScale = 'ringScale' in data ? data.ringScale : 1;\n\n return (\n <>\n {/* Rotating conic gradient - reactive size */}\n <div\n className={cn('absolute rounded-xl -z-10', blur)}\n style={{\n inset: `-${inset}px`,\n background: `conic-gradient(\n from ${data.rotation}deg,\n hsl(${colors[0]} / ${data.colors[0]?.opacity || 0.5}),\n hsl(${colors[1] || colors[0]} / ${data.colors[1]?.opacity || 0.7}),\n hsl(${colors[2] || colors[0]} / ${data.colors[2]?.opacity || 0.5}),\n hsl(${colors[0]} / ${data.colors[1]?.opacity || 0.7}),\n hsl(${colors[0]} / ${data.colors[0]?.opacity || 0.5})\n )`,\n opacity: isPlaying ? 1 : 0,\n transition: 'all 0.08s ease-out',\n }}\n />\n\n {/* Inner border */}\n <div\n className=\"absolute -inset-1 rounded-lg bg-background -z-10\"\n style={{ opacity: isPlaying ? 1 : 0, transition: 'opacity 0.1s' }}\n />\n\n {/* Bass pulse glow - reactive size */}\n <div\n className={cn('absolute rounded-2xl -z-10', blur)}\n style={{\n inset: `-${pulseInset}px`,\n background: `radial-gradient(circle, hsl(${colors[0]} / 0.7) 0%, hsl(${colors[0]} / 0.3) 50%, transparent 70%)`,\n opacity: isPlaying ? data.pulseOpacity : 0,\n transform: `scale(${data.pulseScale})`,\n transition: 'all 0.08s ease-out',\n }}\n />\n\n {/* Outer ring glow */}\n <div\n className=\"absolute rounded-3xl -z-10 blur-2xl\"\n style={{\n inset: `-${pulseInset + 30}px`,\n background: `radial-gradient(circle, hsl(${colors[1] || colors[0]} / 0.4) 0%, transparent 60%)`,\n opacity: isPlaying ? ringOpacity : 0,\n transform: `scale(${ringScale})`,\n transition: 'all 0.08s ease-out',\n }}\n />\n </>\n );\n}\n","'use client';\n\n/**\n * MeshEffect - Mesh gradient blobs that react to audio\n */\n\nimport { cn } from '../../../../_shared';\nimport type { calculateMeshGradients } from '../../../effects';\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\ninterface MeshEffectProps {\n gradients: ReturnType<typeof calculateMeshGradients>;\n blur: string;\n isPlaying: boolean;\n}\n\n// =============================================================================\n// COMPONENT\n// =============================================================================\n\nexport function MeshEffect({ gradients, isPlaying }: MeshEffectProps) {\n return (\n <>\n {gradients.map((g, i) => {\n const isCenter = 'isCenter' in g && g.isCenter;\n const scale = 'scale' in g ? g.scale : 1;\n const rotation = 'rotation' in g ? g.rotation : 0;\n const itemBlur = 'blur' in g ? g.blur : 'blur-2xl';\n\n return (\n <div\n key={i}\n className={cn('absolute rounded-full -z-10', itemBlur)}\n style={{\n width: g.width,\n height: g.height,\n top: 'top' in g ? g.top : undefined,\n bottom: 'bottom' in g ? g.bottom : undefined,\n left: 'left' in g ? g.left : undefined,\n right: 'right' in g ? g.right : undefined,\n background: isCenter\n ? `radial-gradient(circle, hsl(${g.color} / 0.6) 0%, hsl(${g.color} / 0.3) 30%, transparent 60%)`\n : `radial-gradient(circle, hsl(${g.color}) 0%, hsl(${g.color} / 0.5) 30%, transparent 65%)`,\n opacity: isPlaying ? g.opacity : 0,\n transform: isCenter\n ? `translate(-50%, -50%) scale(${scale})`\n : `scale(${scale}) rotate(${rotation}deg)`,\n transition: 'all 0.08s ease-out',\n }}\n />\n );\n })}\n </>\n );\n}\n","'use client';\n\n/**\n * AudioReactiveCover - Album art with audio-reactive animations\n *\n * Uses effects utilities for clean data preparation before render.\n * Click on cover to switch between effect variants.\n *\n * Must be used within HybridAudioProvider context.\n */\n\nimport { type ReactNode } from 'react';\nimport { cn } from '../../../_shared';\nimport { useHybridAudioLevels, useHybridAudioState } from '../../context/HybridAudioProvider';\nimport {\n type EffectVariant,\n type EffectIntensity,\n type EffectColorScheme,\n getEffectConfig,\n prepareEffectColors,\n calculateGlowLayers,\n calculateOrbs,\n calculateMeshGradients,\n calculateSpotlight,\n EFFECT_ANIMATIONS,\n} from '../../effects';\nimport { GlowEffect, OrbsEffect, SpotlightEffect, MeshEffect, type GlowEffectData } from './effects';\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport interface AudioReactiveCoverProps {\n children: ReactNode;\n /** 'sm' | 'md' | 'lg' = fixed sizes; 'full' = stretch to container width (aspect-square) */\n size?: 'sm' | 'md' | 'lg' | 'full';\n variant?: EffectVariant;\n intensity?: EffectIntensity;\n colorScheme?: EffectColorScheme;\n onClick?: () => void;\n className?: string;\n}\n\n// =============================================================================\n// CONSTANTS\n// =============================================================================\n\nconst SIZES = {\n sm: { container: 'w-32 h-32', orbBase: 40 },\n md: { container: 'w-40 h-40', orbBase: 50 },\n lg: { container: 'w-48 h-48', orbBase: 60 },\n full: { container: 'w-full sm:max-w-xs aspect-square mx-auto', orbBase: 60 },\n};\n\n// =============================================================================\n// COMPONENT\n// =============================================================================\n\nexport function AudioReactiveCover({\n children,\n size = 'lg',\n variant = 'spotlight',\n intensity = 'medium',\n colorScheme = 'primary',\n onClick,\n className,\n}: AudioReactiveCoverProps) {\n // Get audio state from HybridAudioProvider context\n const { isPlaying } = useHybridAudioState();\n const levels = useHybridAudioLevels();\n\n // =========================================================================\n // PREPARE DATA BEFORE RENDER\n // =========================================================================\n\n const sizeConfig = SIZES[size];\n const effectConfig = getEffectConfig(intensity);\n const { colors, hueShift } = prepareEffectColors(colorScheme, levels);\n\n // Calculate scale based on overall level\n const containerScale = 1 + levels.overall * effectConfig.scale;\n\n // Prepare effect-specific data - NO memoization for real-time reactivity\n const glowData: GlowEffectData | null = variant === 'glow' ? {\n layers: calculateGlowLayers(levels, effectConfig, colors),\n hueShift,\n showPulseRings: levels.bass > 0.5,\n showSparkle: levels.high > 0.4,\n } : null;\n\n const orbsData = variant === 'orbs'\n ? calculateOrbs(levels, effectConfig, colors, sizeConfig.orbBase)\n : null;\n\n const meshData = variant === 'mesh'\n ? calculateMeshGradients(levels, effectConfig, colors)\n : null;\n\n const spotlightData = variant === 'spotlight'\n ? calculateSpotlight(levels, effectConfig, colors, levels.mid * 360)\n : null;\n\n // =========================================================================\n // RENDER\n // =========================================================================\n\n return (\n <div\n className={cn('relative', sizeConfig.container, className)}\n style={{\n transform: `scale(${containerScale})`,\n transition: 'transform 0.1s ease-out',\n }}\n >\n {/* Effect layers container - under cover, non-interactive */}\n <div className=\"absolute inset-0 z-0 pointer-events-none overflow-visible\">\n {glowData && (\n <GlowEffect data={glowData} colors={colors} isPlaying={isPlaying} />\n )}\n\n {orbsData && (\n <OrbsEffect orbs={orbsData} blur={effectConfig.blur} isPlaying={isPlaying} />\n )}\n\n {spotlightData && (\n <SpotlightEffect data={spotlightData} colors={colors} blur={effectConfig.blur} isPlaying={isPlaying} />\n )}\n\n {meshData && (\n <MeshEffect gradients={meshData} blur={effectConfig.blur} isPlaying={isPlaying} />\n )}\n </div>\n\n {/* Content (cover art) */}\n <div\n className=\"relative w-full h-full rounded-lg overflow-hidden shadow-2xl z-10 bg-background cursor-pointer\"\n onClick={onClick}\n role={onClick ? 'button' : undefined}\n tabIndex={onClick ? 0 : undefined}\n onKeyDown={onClick ? (e) => e.key === 'Enter' && onClick() : undefined}\n >\n {children}\n </div>\n\n {/* Inject animations once */}\n <style dangerouslySetInnerHTML={{ __html: EFFECT_ANIMATIONS }} />\n </div>\n );\n}\n\nexport default AudioReactiveCover;\n","'use client';\n\n/**\n * HybridSimplePlayer - Easy-to-use hybrid audio player wrapper\n *\n * Combines HybridAudioProvider + HybridAudioPlayer + optional reactive cover\n * in a single component with sensible defaults.\n *\n * Uses native HTML5 audio for playback (no crackling) with Web Audio API\n * for visualization only.\n *\n * @example\n * // Minimal usage\n * <HybridSimplePlayer src=\"https://example.com/audio.mp3\" />\n *\n * @example\n * // With cover art and reactive effects\n * <HybridSimplePlayer\n * src={audioUrl}\n * title=\"Track Title\"\n * artist=\"Artist Name\"\n * coverArt=\"/path/to/cover.jpg\"\n * reactiveCover\n * variant=\"spotlight\"\n * />\n */\n\nimport { type ReactNode } from 'react';\nimport { Music } from 'lucide-react';\nimport { cn } from '@djangocfg/ui-core';\n\nimport { HybridAudioProvider } from '../context/HybridAudioProvider';\nimport { HybridAudioPlayer } from './HybridAudioPlayer';\nimport { AudioReactiveCover } from './ReactiveCover';\nimport { VisualizationProvider, useVisualization } from '../hooks';\nimport type { EffectIntensity, EffectColorScheme } from '../effects';\nimport type { VisualizationVariant } from '../hooks';\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport interface HybridSimplePlayerProps {\n /** Audio source URL */\n src: string;\n\n /** Track title */\n title?: string;\n\n /** Artist name */\n artist?: string;\n\n /** Cover art URL or ReactNode */\n coverArt?: string | ReactNode;\n\n /** Cover art size */\n coverSize?: 'sm' | 'md' | 'lg';\n\n /** Show frequency waveform */\n showWaveform?: boolean;\n\n /** Waveform visualization mode */\n waveformMode?: 'frequency' | 'static';\n\n /** Waveform height in pixels */\n waveformHeight?: number;\n\n /** Show timer */\n showTimer?: boolean;\n\n /** Show volume control */\n showVolume?: boolean;\n\n /** Show loop/repeat button */\n showLoop?: boolean;\n\n /** Enable audio-reactive cover effects */\n reactiveCover?: boolean;\n\n /** Reactive effect variant */\n variant?: VisualizationVariant;\n\n /** Reactive effect intensity */\n intensity?: EffectIntensity;\n\n /** Reactive effect color scheme */\n colorScheme?: EffectColorScheme;\n\n /** Auto-play on load */\n autoPlay?: boolean;\n\n /** Loop playback */\n loop?: boolean;\n\n /** Initial volume (0-1) */\n initialVolume?: number;\n\n /** Layout direction */\n layout?: 'vertical' | 'horizontal';\n\n /** Additional class name */\n className?: string;\n\n /** Callbacks */\n onPlay?: () => void;\n onPause?: () => void;\n onEnded?: () => void;\n onError?: (error: Error) => void;\n}\n\n// =============================================================================\n// CONSTANTS\n// =============================================================================\n\nconst COVER_SIZES = {\n sm: 'w-24 h-24',\n md: 'w-32 h-32',\n lg: 'w-48 h-48',\n};\n\n// In horizontal layout cover stays fixed-size; in vertical it fills the full width\nconst COVER_SIZE_FOR_LAYOUT = (coverSize: 'sm' | 'md' | 'lg', isHorizontal: boolean) =>\n isHorizontal ? coverSize : 'full';\n\n// =============================================================================\n// COMPONENT\n// =============================================================================\n\nexport function HybridSimplePlayer(props: HybridSimplePlayerProps) {\n return (\n <VisualizationProvider>\n <HybridSimplePlayerContent {...props} />\n </VisualizationProvider>\n );\n}\n\nfunction HybridSimplePlayerContent({\n src,\n title,\n artist,\n coverArt,\n coverSize = 'md',\n showWaveform = true,\n waveformMode = 'frequency',\n waveformHeight = 64,\n showTimer = true,\n showVolume = true,\n showLoop = true,\n reactiveCover = true,\n variant,\n intensity,\n colorScheme,\n autoPlay = false,\n loop = false,\n initialVolume = 1,\n layout = 'vertical',\n className,\n onPlay,\n onPause,\n onEnded,\n onError,\n}: HybridSimplePlayerProps) {\n const { settings: vizSettings, nextVariant } = useVisualization();\n\n // Determine effective variant (from props or localStorage settings)\n const effectiveVariant =\n variant ?? (vizSettings.variant !== 'none' ? vizSettings.variant : 'spotlight');\n const effectiveIntensity = intensity ?? vizSettings.intensity;\n const effectiveColorScheme = colorScheme ?? vizSettings.colorScheme;\n\n // Show reactive cover if enabled and variant is not 'none'\n const showReactiveCover = reactiveCover && effectiveVariant !== 'none';\n\n // Render cover art content\n const renderCoverContent = () => {\n if (typeof coverArt === 'string') {\n return (\n <img src={coverArt} alt={title || 'Album cover'} className=\"w-full h-full object-cover\" />\n );\n }\n\n if (coverArt) {\n return coverArt;\n }\n\n // Default placeholder\n return (\n <div className=\"w-full h-full bg-muted/30 flex items-center justify-center\">\n <Music className=\"w-1/3 h-1/3 text-muted-foreground/50\" />\n </div>\n );\n };\n\n const isHorizontal = layout === 'horizontal';\n\n return (\n <HybridAudioProvider\n src={src}\n autoPlay={autoPlay}\n loop={loop}\n initialVolume={initialVolume}\n onPlay={onPlay}\n onPause={onPause}\n onEnded={onEnded}\n onError={onError}\n >\n <div\n className={cn(\n 'flex gap-4',\n isHorizontal ? 'flex-row items-center' : 'flex-col items-center',\n className\n )}\n >\n {/* Cover Art */}\n {(coverArt || reactiveCover) && (\n <div className={cn('flex flex-col items-center gap-2', isHorizontal ? 'shrink-0' : 'w-full')}>\n {showReactiveCover ? (\n <AudioReactiveCover\n size={COVER_SIZE_FOR_LAYOUT(coverSize, isHorizontal)}\n variant={effectiveVariant as 'glow' | 'orbs' | 'spotlight' | 'mesh'}\n intensity={effectiveIntensity}\n colorScheme={effectiveColorScheme}\n onClick={nextVariant}\n >\n <div className={cn('rounded-lg overflow-hidden', isHorizontal ? COVER_SIZES[coverSize] : 'w-full h-full')}>\n {renderCoverContent()}\n </div>\n </AudioReactiveCover>\n ) : (\n <div\n className={cn(\n 'rounded-lg overflow-hidden shadow-lg cursor-pointer',\n isHorizontal ? COVER_SIZES[coverSize] : 'w-full sm:max-w-xs aspect-square mx-auto'\n )}\n onClick={nextVariant}\n role=\"button\"\n tabIndex={0}\n onKeyDown={(e) => e.key === 'Enter' && nextVariant()}\n >\n {renderCoverContent()}\n </div>\n )}\n\n {/* Effect indicator */}\n {reactiveCover && (\n <span className=\"text-[10px] uppercase tracking-wider text-muted-foreground/50 select-none\">\n {vizSettings.variant === 'none' ? 'off' : vizSettings.variant}\n </span>\n )}\n </div>\n )}\n\n {/* Track Info + Player */}\n <div\n className={cn('flex flex-col gap-3', isHorizontal ? 'flex-1 min-w-0' : 'w-full')}\n >\n {/* Track Info */}\n {(title || artist) && (\n <div className={cn('text-center', isHorizontal && 'text-left')}>\n {title && (\n <h3 className=\"text-base font-medium text-foreground truncate\">{title}</h3>\n )}\n {artist && <p className=\"text-sm text-muted-foreground truncate\">{artist}</p>}\n </div>\n )}\n\n {/* Audio Player */}\n <HybridAudioPlayer\n showControls\n showWaveform={showWaveform}\n waveformMode={waveformMode}\n waveformHeight={waveformHeight}\n showTimer={showTimer}\n showVolume={showVolume}\n showLoop={showLoop}\n className=\"border-0 bg-transparent\"\n />\n </div>\n </div>\n </HybridAudioProvider>\n );\n}\n\nexport default HybridSimplePlayer;\n","'use client';\n\n/**\n * HybridCompactPlayer - Single-row audio player\n *\n * Designed for tight spaces: play/pause + waveform + timer.\n * No cover art, no volume slider, no skip buttons.\n *\n * @example\n * <HybridCompactPlayer src=\"https://example.com/audio.mp3\" title=\"Rain & Thunder\" />\n *\n * @example\n * // Lazy-loaded (preferred in app)\n * <LazyHybridCompactPlayer src={url} autoPlay />\n */\n\nimport { type ReactNode } from 'react';\nimport { Play, Pause, Loader2 } from 'lucide-react';\nimport { cn } from '@djangocfg/ui-core';\nimport { Button } from '../../_shared';\n\nimport { HybridAudioProvider } from '../context/HybridAudioProvider';\nimport { HybridWaveform } from './HybridWaveform';\nimport { useHybridAudioContext } from '../context/HybridAudioProvider';\nimport { formatTime } from '../utils';\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport interface HybridCompactPlayerProps {\n /** Audio source URL */\n src: string;\n /** Track title (shown as tooltip / aria-label) */\n title?: string;\n /** Auto-play on load */\n autoPlay?: boolean;\n /** Loop playback */\n loop?: boolean;\n /** Initial volume (0-1) */\n initialVolume?: number;\n /** Waveform visualization mode */\n waveformMode?: 'frequency' | 'static';\n /** Show timer */\n showTimer?: boolean;\n /** Button size — 'sm' (h-6 w-6) | 'md' (h-8 w-8, default) */\n buttonSize?: 'sm' | 'md';\n /** Additional class name */\n className?: string;\n /** Callbacks */\n onPlay?: () => void;\n onPause?: () => void;\n onEnded?: () => void;\n onError?: (error: Error) => void;\n}\n\n// =============================================================================\n// COMPONENT\n// =============================================================================\n\nexport function HybridCompactPlayer({\n src,\n title,\n autoPlay = false,\n loop = false,\n initialVolume = 1,\n waveformMode = 'frequency',\n showTimer = true,\n buttonSize = 'md',\n className,\n onPlay,\n onPause,\n onEnded,\n onError,\n}: HybridCompactPlayerProps): ReactNode {\n return (\n <HybridAudioProvider\n src={src}\n autoPlay={autoPlay}\n loop={loop}\n initialVolume={initialVolume}\n onPlay={onPlay}\n onPause={onPause}\n onEnded={onEnded}\n onError={onError}\n >\n <HybridCompactPlayerInner\n title={title}\n waveformMode={waveformMode}\n showTimer={showTimer}\n buttonSize={buttonSize}\n className={className}\n />\n </HybridAudioProvider>\n );\n}\n\n// =============================================================================\n// INNER (needs context)\n// =============================================================================\n\nconst BUTTON_SIZE = {\n sm: 'h-6 w-6',\n md: 'h-8 w-8',\n} as const;\n\ninterface InnerProps {\n title?: string;\n waveformMode: 'frequency' | 'static';\n showTimer: boolean;\n buttonSize: 'sm' | 'md';\n className?: string;\n}\n\nfunction HybridCompactPlayerInner({ title, waveformMode, showTimer, buttonSize, className }: InnerProps) {\n const { state, controls } = useHybridAudioContext();\n const isLoading = !state.isReady;\n\n return (\n <div className={cn('flex items-center gap-2 w-full', className)}>\n {/* Play / Pause */}\n <Button\n variant=\"outline\"\n size=\"icon\"\n className={cn(BUTTON_SIZE[buttonSize], 'flex-shrink-0')}\n onClick={controls.togglePlay}\n disabled={!state.isReady && !isLoading}\n title={title ?? (state.isPlaying ? 'Pause' : 'Play')}\n aria-label={state.isPlaying ? 'Pause' : 'Play'}\n >\n {isLoading ? (\n <Loader2 className=\"h-3.5 w-3.5 animate-spin\" />\n ) : state.isPlaying ? (\n <Pause className=\"h-3.5 w-3.5\" />\n ) : (\n <Play className=\"h-3.5 w-3.5 ml-0.5\" />\n )}\n </Button>\n\n {/* Waveform */}\n <div className=\"flex-1 min-w-0\">\n <HybridWaveform\n mode={waveformMode}\n height={32}\n barWidth={2}\n barGap={1}\n className={cn(isLoading && 'opacity-40')}\n />\n </div>\n\n {/* Timer */}\n {showTimer && (\n <span className=\"text-[11px] text-muted-foreground tabular-nums flex-shrink-0\">\n {formatTime(state.currentTime)}\n <span className=\"text-muted-foreground/50\"> / </span>\n {formatTime(state.duration)}\n </span>\n )}\n </div>\n );\n}\n\nexport default HybridCompactPlayer;\n"]}
|
|
@@ -8,6 +8,7 @@ var i18n = require('@djangocfg/i18n');
|
|
|
8
8
|
var zustand = require('zustand');
|
|
9
9
|
var jsxRuntime = require('react/jsx-runtime');
|
|
10
10
|
var lib = require('@djangocfg/ui-core/lib');
|
|
11
|
+
var palette = require('@djangocfg/ui-core/styles/palette');
|
|
11
12
|
var uiCore = require('@djangocfg/ui-core');
|
|
12
13
|
|
|
13
14
|
var useAudioBusStore = zustand.create((set) => ({
|
|
@@ -531,12 +532,18 @@ var HybridWaveform = react.memo(/* @__PURE__ */ chunkWGEGR3DF_cjs.__name(functio
|
|
|
531
532
|
barWidth = 3,
|
|
532
533
|
barGap = 2,
|
|
533
534
|
barRadius = 2,
|
|
534
|
-
progressColor
|
|
535
|
-
waveColor
|
|
536
|
-
bufferedColor
|
|
535
|
+
progressColor,
|
|
536
|
+
waveColor,
|
|
537
|
+
bufferedColor,
|
|
537
538
|
className,
|
|
538
539
|
onSeek
|
|
539
540
|
}) {
|
|
541
|
+
const themePrimary = palette.useThemeColor("primary");
|
|
542
|
+
const themePrimaryWave = palette.useThemeColor("primary", 0.3);
|
|
543
|
+
const themePrimaryBuffered = palette.useThemeColor("primary", 0.15);
|
|
544
|
+
const resolvedProgressColor = progressColor ?? themePrimary;
|
|
545
|
+
const resolvedWaveColor = waveColor ?? themePrimaryWave;
|
|
546
|
+
const resolvedBufferedColor = bufferedColor ?? themePrimaryBuffered;
|
|
540
547
|
const canvasRef = react.useRef(null);
|
|
541
548
|
const containerRef = react.useRef(null);
|
|
542
549
|
const animationRef = react.useRef(null);
|
|
@@ -570,7 +577,7 @@ var HybridWaveform = react.memo(/* @__PURE__ */ chunkWGEGR3DF_cjs.__name(functio
|
|
|
570
577
|
}
|
|
571
578
|
ctx.clearRect(0, 0, width, canvasHeight);
|
|
572
579
|
if (state.buffered && state.duration > 0) {
|
|
573
|
-
ctx.fillStyle =
|
|
580
|
+
ctx.fillStyle = resolvedBufferedColor;
|
|
574
581
|
for (let i = 0; i < state.buffered.length; i++) {
|
|
575
582
|
const start = state.buffered.start(i) / state.duration * width;
|
|
576
583
|
const end = state.buffered.end(i) / state.duration * width;
|
|
@@ -591,7 +598,7 @@ var HybridWaveform = react.memo(/* @__PURE__ */ chunkWGEGR3DF_cjs.__name(functio
|
|
|
591
598
|
}
|
|
592
599
|
const x = i * (barWidth + barGap) * dpr;
|
|
593
600
|
const y = (canvasHeight - barHeight) / 2;
|
|
594
|
-
ctx.fillStyle = x < progressX ?
|
|
601
|
+
ctx.fillStyle = x < progressX ? resolvedProgressColor : resolvedWaveColor;
|
|
595
602
|
const radius = barRadius * dpr;
|
|
596
603
|
const rectWidth = barWidth * dpr;
|
|
597
604
|
ctx.beginPath();
|
|
@@ -610,9 +617,9 @@ var HybridWaveform = react.memo(/* @__PURE__ */ chunkWGEGR3DF_cjs.__name(functio
|
|
|
610
617
|
barWidth,
|
|
611
618
|
barGap,
|
|
612
619
|
barRadius,
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
620
|
+
resolvedProgressColor,
|
|
621
|
+
resolvedWaveColor,
|
|
622
|
+
resolvedBufferedColor
|
|
616
623
|
]);
|
|
617
624
|
const renderStatic = react.useCallback(() => {
|
|
618
625
|
const canvas = canvasRef.current;
|
|
@@ -623,7 +630,7 @@ var HybridWaveform = react.memo(/* @__PURE__ */ chunkWGEGR3DF_cjs.__name(functio
|
|
|
623
630
|
const dpr = window.devicePixelRatio || 1;
|
|
624
631
|
ctx.clearRect(0, 0, width, canvasHeight);
|
|
625
632
|
if (state.buffered && state.duration > 0) {
|
|
626
|
-
ctx.fillStyle =
|
|
633
|
+
ctx.fillStyle = resolvedBufferedColor;
|
|
627
634
|
for (let i = 0; i < state.buffered.length; i++) {
|
|
628
635
|
const start = state.buffered.start(i) / state.duration * width;
|
|
629
636
|
const end = state.buffered.end(i) / state.duration * width;
|
|
@@ -632,16 +639,16 @@ var HybridWaveform = react.memo(/* @__PURE__ */ chunkWGEGR3DF_cjs.__name(functio
|
|
|
632
639
|
}
|
|
633
640
|
const progress = state.duration > 0 ? state.currentTime / state.duration : 0;
|
|
634
641
|
const progressWidth = width * progress;
|
|
635
|
-
ctx.fillStyle =
|
|
642
|
+
ctx.fillStyle = resolvedWaveColor;
|
|
636
643
|
ctx.fillRect(0, canvasHeight / 2 - 2 * dpr, width, 4 * dpr);
|
|
637
|
-
ctx.fillStyle =
|
|
644
|
+
ctx.fillStyle = resolvedProgressColor;
|
|
638
645
|
ctx.fillRect(0, canvasHeight / 2 - 2 * dpr, progressWidth, 4 * dpr);
|
|
639
646
|
if (progress > 0) {
|
|
640
647
|
ctx.beginPath();
|
|
641
648
|
ctx.arc(progressWidth, canvasHeight / 2, 6 * dpr, 0, Math.PI * 2);
|
|
642
649
|
ctx.fill();
|
|
643
650
|
}
|
|
644
|
-
}, [state.buffered, state.duration, state.currentTime,
|
|
651
|
+
}, [state.buffered, state.duration, state.currentTime, resolvedProgressColor, resolvedWaveColor, resolvedBufferedColor]);
|
|
645
652
|
react.useEffect(() => {
|
|
646
653
|
const container = containerRef.current;
|
|
647
654
|
const canvas = canvasRef.current;
|
|
@@ -1537,6 +1544,7 @@ function HybridCompactPlayer({
|
|
|
1537
1544
|
initialVolume = 1,
|
|
1538
1545
|
waveformMode = "frequency",
|
|
1539
1546
|
showTimer = true,
|
|
1547
|
+
buttonSize = "md",
|
|
1540
1548
|
className,
|
|
1541
1549
|
onPlay,
|
|
1542
1550
|
onPause,
|
|
@@ -1560,6 +1568,7 @@ function HybridCompactPlayer({
|
|
|
1560
1568
|
title,
|
|
1561
1569
|
waveformMode,
|
|
1562
1570
|
showTimer,
|
|
1571
|
+
buttonSize,
|
|
1563
1572
|
className
|
|
1564
1573
|
}
|
|
1565
1574
|
)
|
|
@@ -1567,7 +1576,11 @@ function HybridCompactPlayer({
|
|
|
1567
1576
|
);
|
|
1568
1577
|
}
|
|
1569
1578
|
chunkWGEGR3DF_cjs.__name(HybridCompactPlayer, "HybridCompactPlayer");
|
|
1570
|
-
|
|
1579
|
+
var BUTTON_SIZE = {
|
|
1580
|
+
sm: "h-6 w-6",
|
|
1581
|
+
md: "h-8 w-8"
|
|
1582
|
+
};
|
|
1583
|
+
function HybridCompactPlayerInner({ title, waveformMode, showTimer, buttonSize, className }) {
|
|
1571
1584
|
const { state, controls } = useHybridAudioContext();
|
|
1572
1585
|
const isLoading = !state.isReady;
|
|
1573
1586
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: uiCore.cn("flex items-center gap-2 w-full", className), children: [
|
|
@@ -1576,7 +1589,7 @@ function HybridCompactPlayerInner({ title, waveformMode, showTimer, className })
|
|
|
1576
1589
|
{
|
|
1577
1590
|
variant: "outline",
|
|
1578
1591
|
size: "icon",
|
|
1579
|
-
className: "
|
|
1592
|
+
className: uiCore.cn(BUTTON_SIZE[buttonSize], "flex-shrink-0"),
|
|
1580
1593
|
onClick: controls.togglePlay,
|
|
1581
1594
|
disabled: !state.isReady && !isLoading,
|
|
1582
1595
|
title: title ?? (state.isPlaying ? "Pause" : "Play"),
|
|
@@ -1639,5 +1652,5 @@ exports.useHybridAudioLevels = useHybridAudioLevels;
|
|
|
1639
1652
|
exports.useHybridAudioState = useHybridAudioState;
|
|
1640
1653
|
exports.useHybridWebAudio = useHybridWebAudio;
|
|
1641
1654
|
exports.useVisualization = useVisualization;
|
|
1642
|
-
//# sourceMappingURL=chunk-
|
|
1643
|
-
//# sourceMappingURL=chunk-
|
|
1655
|
+
//# sourceMappingURL=chunk-DF6ORMTF.cjs.map
|
|
1656
|
+
//# sourceMappingURL=chunk-DF6ORMTF.cjs.map
|