@djangocfg/ui-nextjs 2.1.65 → 2.1.67

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.
Files changed (92) hide show
  1. package/package.json +13 -8
  2. package/src/blocks/SplitHero/SplitHeroMedia.tsx +2 -1
  3. package/src/stores/index.ts +8 -0
  4. package/src/stores/mediaCache.ts +464 -0
  5. package/src/tools/AudioPlayer/@refactoring/00-PLAN.md +148 -0
  6. package/src/tools/AudioPlayer/@refactoring/01-TYPES.md +301 -0
  7. package/src/tools/AudioPlayer/@refactoring/02-HOOKS.md +281 -0
  8. package/src/tools/AudioPlayer/@refactoring/03-CONTEXT.md +328 -0
  9. package/src/tools/AudioPlayer/@refactoring/04-COMPONENTS.md +251 -0
  10. package/src/tools/AudioPlayer/@refactoring/05-EFFECTS.md +427 -0
  11. package/src/tools/AudioPlayer/@refactoring/06-UTILS-AND-INDEX.md +193 -0
  12. package/src/tools/AudioPlayer/@refactoring/07-EXECUTION-CHECKLIST.md +146 -0
  13. package/src/tools/AudioPlayer/README.md +325 -0
  14. package/src/tools/AudioPlayer/components/AudioEqualizer.tsx +200 -0
  15. package/src/tools/AudioPlayer/components/AudioPlayer.tsx +231 -0
  16. package/src/tools/AudioPlayer/components/AudioShortcutsPopover.tsx +99 -0
  17. package/src/tools/AudioPlayer/components/ReactiveCover/AudioReactiveCover.tsx +147 -0
  18. package/src/tools/AudioPlayer/components/ReactiveCover/effects/GlowEffect.tsx +110 -0
  19. package/src/tools/AudioPlayer/components/ReactiveCover/effects/MeshEffect.tsx +58 -0
  20. package/src/tools/AudioPlayer/components/ReactiveCover/effects/OrbsEffect.tsx +45 -0
  21. package/src/tools/AudioPlayer/components/ReactiveCover/effects/SpotlightEffect.tsx +82 -0
  22. package/src/tools/AudioPlayer/components/ReactiveCover/effects/index.ts +8 -0
  23. package/src/tools/AudioPlayer/components/ReactiveCover/index.ts +6 -0
  24. package/src/tools/AudioPlayer/components/SimpleAudioPlayer.tsx +280 -0
  25. package/src/tools/AudioPlayer/components/VisualizationToggle.tsx +64 -0
  26. package/src/tools/AudioPlayer/components/index.ts +21 -0
  27. package/src/tools/AudioPlayer/context/AudioProvider.tsx +292 -0
  28. package/src/tools/AudioPlayer/context/index.ts +11 -0
  29. package/src/tools/AudioPlayer/context/selectors.ts +96 -0
  30. package/src/tools/AudioPlayer/effects/index.ts +412 -0
  31. package/src/tools/AudioPlayer/hooks/index.ts +29 -0
  32. package/src/tools/AudioPlayer/hooks/useAudioAnalysis.ts +110 -0
  33. package/src/tools/AudioPlayer/hooks/useAudioHotkeys.ts +149 -0
  34. package/src/tools/AudioPlayer/hooks/useSharedWebAudio.ts +106 -0
  35. package/src/tools/AudioPlayer/hooks/useVisualization.tsx +201 -0
  36. package/src/tools/AudioPlayer/index.ts +139 -0
  37. package/src/tools/AudioPlayer/types/audio.ts +107 -0
  38. package/src/tools/AudioPlayer/types/components.ts +98 -0
  39. package/src/tools/AudioPlayer/types/effects.ts +73 -0
  40. package/src/tools/AudioPlayer/types/index.ts +35 -0
  41. package/src/tools/AudioPlayer/utils/formatTime.ts +10 -0
  42. package/src/tools/AudioPlayer/utils/index.ts +5 -0
  43. package/src/tools/ImageViewer/@refactoring/00-PLAN.md +71 -0
  44. package/src/tools/ImageViewer/@refactoring/01-TYPES.md +121 -0
  45. package/src/tools/ImageViewer/@refactoring/02-UTILS.md +143 -0
  46. package/src/tools/ImageViewer/@refactoring/03-HOOKS.md +261 -0
  47. package/src/tools/ImageViewer/@refactoring/04-COMPONENTS.md +427 -0
  48. package/src/tools/ImageViewer/@refactoring/05-EXECUTION-CHECKLIST.md +126 -0
  49. package/src/tools/ImageViewer/README.md +174 -0
  50. package/src/tools/ImageViewer/components/ImageInfo.tsx +44 -0
  51. package/src/tools/ImageViewer/components/ImageToolbar.tsx +150 -0
  52. package/src/tools/ImageViewer/components/ImageViewer.tsx +235 -0
  53. package/src/tools/ImageViewer/components/index.ts +7 -0
  54. package/src/tools/ImageViewer/hooks/index.ts +9 -0
  55. package/src/tools/ImageViewer/hooks/useImageLoading.ts +153 -0
  56. package/src/tools/ImageViewer/hooks/useImageTransform.ts +101 -0
  57. package/src/tools/ImageViewer/index.ts +60 -0
  58. package/src/tools/ImageViewer/types.ts +75 -0
  59. package/src/tools/ImageViewer/utils/constants.ts +59 -0
  60. package/src/tools/ImageViewer/utils/index.ts +16 -0
  61. package/src/tools/ImageViewer/utils/lqip.ts +47 -0
  62. package/src/tools/VideoPlayer/@refactoring/00-PLAN.md +91 -0
  63. package/src/tools/VideoPlayer/@refactoring/01-TYPES.md +284 -0
  64. package/src/tools/VideoPlayer/@refactoring/02-UTILS.md +141 -0
  65. package/src/tools/VideoPlayer/@refactoring/03-HOOKS.md +178 -0
  66. package/src/tools/VideoPlayer/@refactoring/04-COMPONENTS.md +95 -0
  67. package/src/tools/VideoPlayer/@refactoring/05-EXECUTION-CHECKLIST.md +139 -0
  68. package/src/tools/VideoPlayer/README.md +212 -187
  69. package/src/tools/VideoPlayer/{VideoControls.tsx → components/VideoControls.tsx} +8 -9
  70. package/src/tools/VideoPlayer/components/VideoErrorFallback.tsx +174 -0
  71. package/src/tools/VideoPlayer/components/VideoPlayer.tsx +201 -0
  72. package/src/tools/VideoPlayer/components/index.ts +14 -0
  73. package/src/tools/VideoPlayer/context/VideoPlayerContext.tsx +52 -0
  74. package/src/tools/VideoPlayer/context/index.ts +8 -0
  75. package/src/tools/VideoPlayer/hooks/index.ts +9 -0
  76. package/src/tools/VideoPlayer/hooks/useVideoPositionCache.ts +109 -0
  77. package/src/tools/VideoPlayer/index.ts +70 -9
  78. package/src/tools/VideoPlayer/providers/NativeProvider.tsx +206 -0
  79. package/src/tools/VideoPlayer/providers/StreamProvider.tsx +401 -0
  80. package/src/tools/VideoPlayer/providers/VidstackProvider.tsx +332 -0
  81. package/src/tools/VideoPlayer/providers/index.ts +8 -0
  82. package/src/tools/VideoPlayer/types/index.ts +38 -0
  83. package/src/tools/VideoPlayer/types/player.ts +116 -0
  84. package/src/tools/VideoPlayer/types/provider.ts +93 -0
  85. package/src/tools/VideoPlayer/types/sources.ts +97 -0
  86. package/src/tools/VideoPlayer/utils/fileSource.ts +78 -0
  87. package/src/tools/VideoPlayer/utils/index.ts +11 -0
  88. package/src/tools/VideoPlayer/utils/resolvers.ts +75 -0
  89. package/src/tools/index.ts +92 -4
  90. package/src/tools/VideoPlayer/NativePlayer.tsx +0 -141
  91. package/src/tools/VideoPlayer/VideoPlayer.tsx +0 -231
  92. package/src/tools/VideoPlayer/types.ts +0 -118
@@ -0,0 +1,178 @@
1
+ # Phase 3: Hooks Extraction
2
+
3
+ ## Goal
4
+
5
+ Extract duplicated video position caching logic into a reusable hook.
6
+
7
+ ## Current Duplication
8
+
9
+ The position caching pattern is duplicated in:
10
+ 1. `VidstackProvider.tsx` (lines ~180-220)
11
+ 2. `StreamProvider.tsx` (lines ~200-240)
12
+
13
+ Both implement:
14
+ - Save position every 5 seconds during playback
15
+ - Restore position when video loads (canPlay)
16
+ - Clear position when video ends
17
+
18
+ ## File to Create
19
+
20
+ ### hooks/useVideoPositionCache.ts
21
+
22
+ ```typescript
23
+ 'use client';
24
+
25
+ /**
26
+ * useVideoPositionCache - Manages video playback position caching
27
+ *
28
+ * Saves position periodically during playback and restores on load.
29
+ */
30
+
31
+ import { useRef, useEffect, useCallback } from 'react';
32
+ import { useVideoCache } from '../../../stores/mediaCache';
33
+
34
+ // =============================================================================
35
+ // TYPES
36
+ // =============================================================================
37
+
38
+ export interface UseVideoPositionCacheOptions {
39
+ /** Unique key for caching (e.g., video URL or stream key) */
40
+ cacheKey: string;
41
+ /** Current playback time in seconds */
42
+ currentTime: number;
43
+ /** Video duration in seconds */
44
+ duration: number;
45
+ /** Whether video is currently playing */
46
+ isPlaying: boolean;
47
+ /** Whether video is ready to play */
48
+ isReady: boolean;
49
+ /** Callback to seek to a specific time */
50
+ onSeek: (time: number) => void;
51
+ }
52
+
53
+ export interface UseVideoPositionCacheReturn {
54
+ /** Manually save current position */
55
+ savePosition: () => void;
56
+ /** Clear saved position */
57
+ clearPosition: () => void;
58
+ }
59
+
60
+ // =============================================================================
61
+ // CONSTANTS
62
+ // =============================================================================
63
+
64
+ /** Save interval in seconds */
65
+ const SAVE_INTERVAL = 5;
66
+
67
+ /** Minimum position to restore (avoid 0 or near-end) */
68
+ const MIN_RESTORE_POSITION = 1;
69
+
70
+ // =============================================================================
71
+ // HOOK
72
+ // =============================================================================
73
+
74
+ export function useVideoPositionCache(
75
+ options: UseVideoPositionCacheOptions
76
+ ): UseVideoPositionCacheReturn {
77
+ const { cacheKey, currentTime, duration, isPlaying, isReady, onSeek } = options;
78
+
79
+ const { saveVideoPosition, getVideoPosition } = useVideoCache();
80
+ const lastSavedTimeRef = useRef<number>(0);
81
+ const hasRestoredRef = useRef<boolean>(false);
82
+
83
+ // Restore position when ready
84
+ useEffect(() => {
85
+ if (!isReady || !cacheKey || hasRestoredRef.current) return;
86
+
87
+ const savedPosition = getVideoPosition(cacheKey);
88
+ if (savedPosition && savedPosition > MIN_RESTORE_POSITION && savedPosition < duration - 1) {
89
+ onSeek(savedPosition);
90
+ }
91
+ hasRestoredRef.current = true;
92
+ }, [isReady, cacheKey, duration, getVideoPosition, onSeek]);
93
+
94
+ // Reset restored flag when cache key changes
95
+ useEffect(() => {
96
+ hasRestoredRef.current = false;
97
+ lastSavedTimeRef.current = 0;
98
+ }, [cacheKey]);
99
+
100
+ // Save position periodically during playback
101
+ useEffect(() => {
102
+ if (!cacheKey || !isPlaying || currentTime <= 0) return;
103
+
104
+ const timeSinceLastSave = currentTime - lastSavedTimeRef.current;
105
+ if (timeSinceLastSave >= SAVE_INTERVAL || timeSinceLastSave < 0) {
106
+ saveVideoPosition(cacheKey, currentTime);
107
+ lastSavedTimeRef.current = currentTime;
108
+ }
109
+ }, [cacheKey, isPlaying, currentTime, saveVideoPosition]);
110
+
111
+ // Save position on pause
112
+ useEffect(() => {
113
+ if (!cacheKey || isPlaying || currentTime <= 0) return;
114
+
115
+ saveVideoPosition(cacheKey, currentTime);
116
+ lastSavedTimeRef.current = currentTime;
117
+ }, [cacheKey, isPlaying, currentTime, saveVideoPosition]);
118
+
119
+ const savePosition = useCallback(() => {
120
+ if (cacheKey && currentTime > 0) {
121
+ saveVideoPosition(cacheKey, currentTime);
122
+ }
123
+ }, [cacheKey, currentTime, saveVideoPosition]);
124
+
125
+ const clearPosition = useCallback(() => {
126
+ if (cacheKey) {
127
+ saveVideoPosition(cacheKey, 0);
128
+ }
129
+ }, [cacheKey, saveVideoPosition]);
130
+
131
+ return {
132
+ savePosition,
133
+ clearPosition,
134
+ };
135
+ }
136
+ ```
137
+
138
+ ### hooks/index.ts
139
+
140
+ ```typescript
141
+ /**
142
+ * VideoPlayer hooks - Public API
143
+ */
144
+
145
+ export { useVideoPositionCache } from './useVideoPositionCache';
146
+ export type {
147
+ UseVideoPositionCacheOptions,
148
+ UseVideoPositionCacheReturn,
149
+ } from './useVideoPositionCache';
150
+ ```
151
+
152
+ ## Usage in Providers
153
+
154
+ After extraction, providers can use:
155
+
156
+ ```typescript
157
+ // In VidstackProvider.tsx
158
+ const { clearPosition } = useVideoPositionCache({
159
+ cacheKey: sourceKey,
160
+ currentTime: player?.currentTime ?? 0,
161
+ duration: player?.duration ?? 0,
162
+ isPlaying: !paused,
163
+ isReady: canPlay,
164
+ onSeek: (time) => player?.currentTime = time,
165
+ });
166
+
167
+ // Clear on video end
168
+ useEffect(() => {
169
+ if (ended) clearPosition();
170
+ }, [ended, clearPosition]);
171
+ ```
172
+
173
+ ## Benefits
174
+
175
+ 1. **DRY** - Single source of truth for position caching logic
176
+ 2. **Testable** - Hook can be unit tested independently
177
+ 3. **Reusable** - Can be used in future video components
178
+ 4. **Maintainable** - Changes only need to be made in one place
@@ -0,0 +1,95 @@
1
+ # Phase 4: Components Organization
2
+
3
+ ## Goal
4
+
5
+ Move standalone components to a dedicated `components/` folder for consistency.
6
+
7
+ ## Current Location
8
+
9
+ ```
10
+ VideoPlayer/
11
+ ├── VideoPlayer.tsx # Main orchestrator
12
+ ├── VideoControls.tsx # Vidstack controls
13
+ ├── VideoErrorFallback.tsx # Error UI
14
+ └── providers/ # Provider implementations
15
+ ```
16
+
17
+ ## Target Location
18
+
19
+ ```
20
+ VideoPlayer/
21
+ ├── components/
22
+ │ ├── index.ts
23
+ │ ├── VideoPlayer.tsx
24
+ │ ├── VideoControls.tsx
25
+ │ └── VideoErrorFallback.tsx
26
+ └── providers/ # Unchanged
27
+ ```
28
+
29
+ ## Files to Create
30
+
31
+ ### components/index.ts
32
+
33
+ ```typescript
34
+ /**
35
+ * VideoPlayer components - Public API
36
+ */
37
+
38
+ export { VideoPlayer } from './VideoPlayer';
39
+ export { VideoControls } from './VideoControls';
40
+ export {
41
+ VideoErrorFallback,
42
+ createVideoErrorFallback,
43
+ } from './VideoErrorFallback';
44
+ ```
45
+
46
+ ## Component Updates
47
+
48
+ ### VideoPlayer.tsx
49
+
50
+ Update imports to use new paths:
51
+
52
+ ```typescript
53
+ // Before
54
+ import { VidstackProvider } from './providers';
55
+ import { NativeProvider } from './providers';
56
+ import { StreamProvider } from './providers';
57
+ import { resolvePlayerMode, isSimpleStreamSource, resolveStreamSource } from './types';
58
+ import { useVideoPlayerContext } from './VideoPlayerContext';
59
+
60
+ // After
61
+ import { VidstackProvider, NativeProvider, StreamProvider } from '../providers';
62
+ import { resolvePlayerMode, isSimpleStreamSource, resolveStreamSource } from '../utils';
63
+ import { useVideoPlayerContext } from '../context';
64
+ ```
65
+
66
+ ### VideoControls.tsx
67
+
68
+ Update imports:
69
+
70
+ ```typescript
71
+ // Before
72
+ import type { ... } from './types';
73
+
74
+ // After
75
+ import type { ... } from '../types';
76
+ ```
77
+
78
+ ### VideoErrorFallback.tsx
79
+
80
+ Update imports:
81
+
82
+ ```typescript
83
+ // Before
84
+ import type { ErrorFallbackProps } from './types';
85
+
86
+ // After
87
+ import type { ErrorFallbackProps } from '../types';
88
+ ```
89
+
90
+ ## Notes
91
+
92
+ - VideoPlayer.tsx is the main entry point, moved to components/
93
+ - Providers stay in their own folder (already well-organized)
94
+ - Context moves to context/ folder
95
+ - All imports updated to reflect new structure
@@ -0,0 +1,139 @@
1
+ # Execution Checklist
2
+
3
+ ## Pre-flight
4
+
5
+ - [ ] Read all current files
6
+ - [ ] Backup or rename original files
7
+ - [ ] Create folder structure
8
+
9
+ ## Phase 1: Folder Structure
10
+
11
+ ```bash
12
+ cd src/tools/VideoPlayer
13
+ mkdir -p types hooks utils components context
14
+ ```
15
+
16
+ - [ ] Create `types/` directory
17
+ - [ ] Create `hooks/` directory
18
+ - [ ] Create `utils/` directory
19
+ - [ ] Create `components/` directory
20
+ - [ ] Create `context/` directory
21
+
22
+ ## Phase 2: Types
23
+
24
+ - [ ] Create `types/sources.ts` - Source type definitions
25
+ - [ ] Create `types/player.ts` - Player config and main types
26
+ - [ ] Create `types/provider.ts` - Provider-specific types
27
+ - [ ] Create `types/index.ts` - Re-exports
28
+ - [ ] Run `pnpm check`
29
+
30
+ ## Phase 3: Utils
31
+
32
+ - [ ] Create `utils/resolvers.ts` - resolvePlayerMode, isSimpleStreamSource
33
+ - [ ] Create `utils/fileSource.ts` - resolveFileSource
34
+ - [ ] Create `utils/index.ts` - Re-exports
35
+ - [ ] Run `pnpm check`
36
+
37
+ ## Phase 4: Hooks
38
+
39
+ - [ ] Create `hooks/useVideoPositionCache.ts` - Position caching logic
40
+ - [ ] Create `hooks/index.ts` - Re-exports
41
+ - [ ] Run `pnpm check`
42
+
43
+ ## Phase 5: Components
44
+
45
+ - [ ] Move `VideoPlayer.tsx` to `components/`
46
+ - [ ] Move `VideoControls.tsx` to `components/`
47
+ - [ ] Move `VideoErrorFallback.tsx` to `components/`
48
+ - [ ] Create `components/index.ts`
49
+ - [ ] Update imports in all moved files
50
+ - [ ] Run `pnpm check`
51
+
52
+ ## Phase 6: Context
53
+
54
+ - [ ] Move `VideoPlayerContext.tsx` to `context/`
55
+ - [ ] Create `context/index.ts`
56
+ - [ ] Update imports
57
+ - [ ] Run `pnpm check`
58
+
59
+ ## Phase 7: Update Providers
60
+
61
+ - [ ] Update imports in `VidstackProvider.tsx`
62
+ - [ ] Update imports in `NativeProvider.tsx`
63
+ - [ ] Update imports in `StreamProvider.tsx`
64
+ - [ ] Optionally integrate `useVideoPositionCache` hook
65
+ - [ ] Run `pnpm check`
66
+
67
+ ## Phase 8: Main Index
68
+
69
+ - [ ] Update `index.ts` with new imports
70
+ - [ ] Verify all exports work
71
+ - [ ] Run `pnpm check`
72
+
73
+ ## Phase 9: Cleanup
74
+
75
+ - [ ] Delete old `types.ts`
76
+ - [ ] Delete old `VideoPlayer.tsx`
77
+ - [ ] Delete old `VideoControls.tsx`
78
+ - [ ] Delete old `VideoErrorFallback.tsx`
79
+ - [ ] Delete old `VideoPlayerContext.tsx`
80
+ - [ ] Run `pnpm check`
81
+ - [ ] Run `pnpm build` (optional)
82
+
83
+ ## Post-flight
84
+
85
+ - [ ] Test video playback (URL source)
86
+ - [ ] Test YouTube embed
87
+ - [ ] Test stream playback
88
+ - [ ] Test error fallback
89
+ - [ ] Verify position caching works
90
+
91
+ ## Final Structure
92
+
93
+ ```
94
+ VideoPlayer/
95
+ ├── index.ts
96
+ ├── README.md
97
+ ├── types/
98
+ │ ├── index.ts
99
+ │ ├── sources.ts
100
+ │ ├── player.ts
101
+ │ └── provider.ts
102
+ ├── hooks/
103
+ │ ├── index.ts
104
+ │ └── useVideoPositionCache.ts
105
+ ├── utils/
106
+ │ ├── index.ts
107
+ │ ├── resolvers.ts
108
+ │ └── fileSource.ts
109
+ ├── components/
110
+ │ ├── index.ts
111
+ │ ├── VideoPlayer.tsx
112
+ │ ├── VideoControls.tsx
113
+ │ └── VideoErrorFallback.tsx
114
+ ├── context/
115
+ │ ├── index.ts
116
+ │ └── VideoPlayerContext.tsx
117
+ └── providers/
118
+ ├── index.ts
119
+ ├── VidstackProvider.tsx
120
+ ├── NativeProvider.tsx
121
+ └── StreamProvider.tsx
122
+ ```
123
+
124
+ ## Metrics
125
+
126
+ | Metric | Before | After |
127
+ |--------|--------|-------|
128
+ | types.ts | 369 lines | Split into 3 files (~100 each) |
129
+ | Total files | 10 | 18 |
130
+ | Hooks | 0 | 1 (useVideoPositionCache) |
131
+ | Utils | 0 (in types.ts) | 2 |
132
+ | Duplicated code | Position caching x2 | Extracted to hook |
133
+
134
+ ## Optional Improvements
135
+
136
+ After main refactoring, consider:
137
+ 1. Integrate `useVideoPositionCache` into providers
138
+ 2. Extract more shared logic from StreamProvider
139
+ 3. Add unit tests for utils and hooks