Skip to content

Commit 3033b65

Browse files
authored
Merge pull request #275 from naomiaro/fix/eliminate-any-types
Eliminate all any types across packages
2 parents 1996ecc + abbd00b commit 3033b65

File tree

20 files changed

+295
-119
lines changed

20 files changed

+295
-119
lines changed

packages/browser/src/AnnotationIntegrationContext.tsx

Lines changed: 54 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,54 @@
11
import { createContext, useContext } from 'react';
2-
import type { AnnotationData } from '@waveform-playlist/core';
2+
import type {
3+
AnnotationData,
4+
AnnotationAction,
5+
AnnotationActionOptions,
6+
RenderAnnotationItemProps,
7+
} from '@waveform-playlist/core';
8+
9+
/**
10+
* Props the browser package passes to the AnnotationText component.
11+
* Mirrors what PlaylistAnnotationList and MediaElementAnnotationList actually use.
12+
*/
13+
export interface AnnotationTextIntegrationProps {
14+
annotations: AnnotationData[];
15+
activeAnnotationId?: string;
16+
shouldScrollToActive?: boolean;
17+
scrollActivePosition?: ScrollLogicalPosition;
18+
scrollActiveContainer?: 'nearest' | 'all';
19+
editable?: boolean;
20+
controls?: AnnotationAction[];
21+
annotationListConfig?: AnnotationActionOptions;
22+
height?: number;
23+
onAnnotationUpdate?: (updatedAnnotations: AnnotationData[]) => void;
24+
renderAnnotationItem?: (props: RenderAnnotationItemProps) => React.ReactNode;
25+
}
26+
27+
/**
28+
* Props the browser package passes to the AnnotationBox component.
29+
* Mirrors what PlaylistVisualization and MediaElementPlaylist actually use.
30+
*/
31+
export interface AnnotationBoxIntegrationProps {
32+
annotationId: string;
33+
annotationIndex: number;
34+
startPosition: number;
35+
endPosition: number;
36+
label?: string;
37+
color?: string;
38+
isActive?: boolean;
39+
onClick?: () => void;
40+
editable?: boolean;
41+
}
42+
43+
/**
44+
* Props the browser package passes to the AnnotationBoxesWrapper component.
45+
* Mirrors what PlaylistVisualization and MediaElementPlaylist actually use.
46+
*/
47+
export interface AnnotationBoxesWrapperIntegrationProps {
48+
children?: React.ReactNode;
49+
height?: number;
50+
width?: number;
51+
}
352

453
/**
554
* Interface for annotation integration provided by @waveform-playlist/annotations.
@@ -12,13 +61,10 @@ export interface AnnotationIntegration {
1261
parseAeneas: (data: unknown) => AnnotationData;
1362
serializeAeneas: (annotation: AnnotationData) => unknown;
1463

15-
// Visualization components (typed loosely since browser controls invocation)
16-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
17-
AnnotationText: React.ComponentType<any>;
18-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
19-
AnnotationBox: React.ComponentType<any>;
20-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
21-
AnnotationBoxesWrapper: React.ComponentType<any>;
64+
// Visualization components (typed with the props the browser package actually passes)
65+
AnnotationText: React.ComponentType<AnnotationTextIntegrationProps>;
66+
AnnotationBox: React.ComponentType<AnnotationBoxIntegrationProps>;
67+
AnnotationBoxesWrapper: React.ComponentType<AnnotationBoxesWrapperIntegrationProps>;
2268

2369
// Control components
2470
ContinuousPlayCheckbox: React.ComponentType<{ checked: boolean; onChange: (checked: boolean) => void; className?: string }>;

packages/browser/src/MediaElementPlaylistContext.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import {
2020
} from '@waveform-playlist/ui-components';
2121
import type { AnnotationData } from '@waveform-playlist/core';
2222
import { extractPeaksFromWaveformData } from './waveformDataLoader';
23+
import type WaveformData from 'waveform-data';
2324
import type { PeakData } from '@waveform-playlist/webaudio-peaks';
2425
import type { ClipPeaks, TrackClipPeaks } from './WaveformPlaylistContext';
2526

@@ -108,7 +109,7 @@ export interface MediaElementPlaylistProviderProps {
108109
controls?: { show: boolean; width: number };
109110
/** Annotations */
110111
annotationList?: {
111-
annotations?: any[];
112+
annotations?: AnnotationData[];
112113
isContinuousPlay?: boolean;
113114
};
114115
/** Width of waveform bars */
@@ -172,7 +173,7 @@ export const MediaElementPlaylistProvider: React.FC<
172173
const annotations = useMemo(() => {
173174
if (!annotationList?.annotations) return [];
174175
if (process.env.NODE_ENV !== 'production' && annotationList.annotations.length > 0) {
175-
const first = annotationList.annotations[0] as Record<string, unknown>;
176+
const first = annotationList.annotations[0] as unknown as Record<string, unknown>;
176177
if (typeof first.start !== 'number' || typeof first.end !== 'number') {
177178
console.error(
178179
'[waveform-playlist] Annotations must have numeric start/end values. ' +
@@ -182,7 +183,7 @@ export const MediaElementPlaylistProvider: React.FC<
182183
return [];
183184
}
184185
}
185-
return annotationList.annotations as AnnotationData[];
186+
return annotationList.annotations;
186187
}, [annotationList?.annotations]);
187188

188189
// Ref for animation loop (avoids restarting loop on annotation change)
@@ -283,7 +284,7 @@ export const MediaElementPlaylistProvider: React.FC<
283284
// Generate peaks from waveform data
284285
useEffect(() => {
285286
const extractedPeaks = extractPeaksFromWaveformData(
286-
track.waveformData as any,
287+
track.waveformData as WaveformData,
287288
samplesPerPixel,
288289
0, // channel index
289290
0, // offset

packages/browser/src/WaveformPlaylistContext.tsx

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import React, { createContext, useContext, useState, useEffect, useRef, useCallback, useMemo, type ReactNode } from 'react';
22
import { ThemeProvider } from 'styled-components';
33
import { TonePlayout, type EffectsFunction, type TrackEffectsFunction } from '@waveform-playlist/playout';
4-
import { type Track, type ClipTrack, type Fade } from '@waveform-playlist/core';
4+
import { type Track, type ClipTrack, type Fade, type AnnotationAction } from '@waveform-playlist/core';
55
import { type TimeFormat, type WaveformPlaylistTheme, defaultTheme } from '@waveform-playlist/ui-components';
66
import { getContext } from 'tone';
77
import { generatePeaks } from './peaksUtil';
88

99
import { extractPeaksFromWaveformData } from './waveformDataLoader';
10+
import type WaveformData from 'waveform-data';
1011
import type { PeakData } from '@waveform-playlist/webaudio-peaks';
1112
import type { AnnotationData } from '@waveform-playlist/core';
1213
import { useTimeFormat, useZoomControls, useMasterVolume } from './hooks';
@@ -73,7 +74,7 @@ export interface WaveformPlaylistContextValue {
7374
setSelection: (start: number, end: number) => void;
7475

7576
// Time format
76-
timeFormat: string;
77+
timeFormat: TimeFormat;
7778
setTimeFormat: (format: TimeFormat) => void;
7879
formatTime: (seconds: number) => string;
7980

@@ -201,7 +202,7 @@ export interface PlaylistDataContextValue {
201202
controls: { show: boolean; width: number };
202203
playoutRef: React.RefObject<TonePlayout | null>;
203204
samplesPerPixel: number;
204-
timeFormat: string;
205+
timeFormat: TimeFormat;
205206
masterVolume: number;
206207
canZoomIn: boolean;
207208
canZoomOut: boolean;
@@ -238,11 +239,11 @@ export interface WaveformPlaylistProviderProps {
238239
width: number;
239240
};
240241
annotationList?: {
241-
annotations?: any[];
242+
annotations?: AnnotationData[];
242243
editable?: boolean;
243244
isContinuousPlay?: boolean;
244245
linkEndpoints?: boolean;
245-
controls?: any[];
246+
controls?: AnnotationAction[];
246247
};
247248
effects?: EffectsFunction;
248249
onReady?: () => void;
@@ -286,7 +287,7 @@ export const WaveformPlaylistProvider: React.FC<WaveformPlaylistProviderProps> =
286287
const annotations = useMemo(() => {
287288
if (!annotationList?.annotations) return [];
288289
if (process.env.NODE_ENV !== 'production' && annotationList.annotations.length > 0) {
289-
const first = annotationList.annotations[0] as Record<string, unknown>;
290+
const first = annotationList.annotations[0] as unknown as Record<string, unknown>;
290291
if (typeof first.start !== 'number' || typeof first.end !== 'number') {
291292
console.error(
292293
'[waveform-playlist] Annotations must have numeric start/end values. ' +
@@ -296,7 +297,7 @@ export const WaveformPlaylistProvider: React.FC<WaveformPlaylistProviderProps> =
296297
return [];
297298
}
298299
}
299-
return annotationList.annotations as AnnotationData[];
300+
return annotationList.annotations;
300301
}, [annotationList?.annotations]);
301302

302303
// Ref for animation loop (avoids restarting loop on annotation change)
@@ -620,7 +621,7 @@ export const WaveformPlaylistProvider: React.FC<WaveformPlaylistProviderProps> =
620621
// Use waveform-data.js to resample and slice as needed
621622
// Pass sample values directly for accuracy
622623
const extractedPeaks = extractPeaksFromWaveformData(
623-
clip.waveformData as any, // Cast to WaveformData type
624+
clip.waveformData as WaveformData,
624625
samplesPerPixel,
625626
0, // channel index
626627
clip.offsetSamples,

packages/browser/src/components/ContextualControls.tsx

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import {
66
AutomaticScrollCheckbox as BaseAutomaticScrollCheckbox,
77
SelectionTimeInputs as BaseSelectionTimeInputs,
88
formatTime,
9-
type TimeFormat,
109
} from '@waveform-playlist/ui-components';
1110
import styled from 'styled-components';
1211
import { usePlaybackAnimation, usePlaylistState, usePlaylistControls, usePlaylistData } from '../WaveformPlaylistContext';
@@ -36,8 +35,8 @@ export const TimeFormatSelect: React.FC<{ className?: string }> = ({ className }
3635

3736
return (
3837
<BaseTimeFormatSelect
39-
value={timeFormat as any}
40-
onChange={setTimeFormat as any}
38+
value={timeFormat}
39+
onChange={setTimeFormat}
4140
className={className}
4241
/>
4342
);
@@ -60,8 +59,7 @@ export const AudioPosition: React.FC<{ className?: string }> = ({ className }) =
6059
const timeRef = useRef<HTMLSpanElement>(null);
6160
const animationFrameRef = useRef<number | null>(null);
6261
const { isPlaying, currentTimeRef, playbackStartTimeRef, audioStartPositionRef } = usePlaybackAnimation();
63-
const { timeFormat } = usePlaylistData();
64-
const format = timeFormat as TimeFormat;
62+
const { timeFormat: format } = usePlaylistData();
6563

6664
useEffect(() => {
6765
const updateTime = () => {

0 commit comments

Comments
 (0)