-
Notifications
You must be signed in to change notification settings - Fork 557
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Release v1.0.2 cherry picks #4991
base: release/v1.0.2
Are you sure you want to change the base?
Changes from all commits
6884c87
ab27a4e
3c68905
8a37106
0048f7b
842efa8
6c0b581
44c04b8
e8be6b6
69d4a7e
e009587
5e4f01b
dd3c8de
7b15892
1ca5e93
6c5387f
eef88ac
6757a66
832af1a
d073a1e
144f43d
b6a5344
6a6a759
6681ad9
1eaf784
2f1cd84
b38cc7d
df48877
7c803ed
19c4e01
5e611c1
28ab8a3
e9f6643
2c3b284
e61c145
6daea1e
586159b
389557c
3d92aab
54d0912
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -7,6 +7,7 @@ import { | |||||||||||||||||
overlayToSx, | ||||||||||||||||||
} from "../utils"; | ||||||||||||||||||
import { ViewPropsType } from "../utils/types"; | ||||||||||||||||||
import { has } from "lodash"; | ||||||||||||||||||
|
||||||||||||||||||
export default function ContainerizedComponent(props: ContainerizedComponent) { | ||||||||||||||||||
const { schema, children } = props; | ||||||||||||||||||
|
@@ -22,7 +23,11 @@ export default function ContainerizedComponent(props: ContainerizedComponent) { | |||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
if (isCompositeView(schema)) { | ||||||||||||||||||
const hasOverlay = !!schema?.view?.overlay; | ||||||||||||||||||
const sxForOverlay = overlayToSx[schema?.view?.overlay] || {}; | ||||||||||||||||||
if (hasOverlay) { | ||||||||||||||||||
sxForOverlay.zIndex = 999; | ||||||||||||||||||
} | ||||||||||||||||||
Comment on lines
+28
to
+30
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Consider using a named constant for z-index value The hardcoded z-index value of 999 should be defined as a named constant at the module level for better maintainability and to prevent potential layering conflicts. +const OVERLAY_Z_INDEX = 999;
// Later in the code
if (hasOverlay) {
- sxForOverlay.zIndex = 999;
+ sxForOverlay.zIndex = OVERLAY_Z_INDEX;
} 📝 Committable suggestion
Suggested change
|
||||||||||||||||||
return ( | ||||||||||||||||||
<Box sx={{ position: "relative", ...sxForOverlay }}> | ||||||||||||||||||
{containerizedChildren} | ||||||||||||||||||
|
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -10,6 +10,8 @@ import { usePanelId, useSetPanelStateById } from "@fiftyone/spaces"; | |||||||||||||||||||||||||||||||||||
import { useTimeline } from "@fiftyone/playback/src/lib/use-timeline"; | ||||||||||||||||||||||||||||||||||||
import _ from "lodash"; | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
const FRAME_LOADED_EVENT = "frames-loaded"; | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
export default function FrameLoaderView(props: ViewPropsType) { | ||||||||||||||||||||||||||||||||||||
const { schema, path, data } = props; | ||||||||||||||||||||||||||||||||||||
const { view = {} } = schema; | ||||||||||||||||||||||||||||||||||||
|
@@ -19,15 +21,16 @@ export default function FrameLoaderView(props: ViewPropsType) { | |||||||||||||||||||||||||||||||||||
const setPanelState = useSetPanelStateById(true); | ||||||||||||||||||||||||||||||||||||
const localIdRef = React.useRef<string>(); | ||||||||||||||||||||||||||||||||||||
const bufm = useRef(new BufferManager()); | ||||||||||||||||||||||||||||||||||||
const frameDataRef = useRef<typeof data.frames>(null); | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
useEffect(() => { | ||||||||||||||||||||||||||||||||||||
localIdRef.current = Math.random().toString(36).substring(7); | ||||||||||||||||||||||||||||||||||||
if (data?.frames) | ||||||||||||||||||||||||||||||||||||
window.dispatchEvent( | ||||||||||||||||||||||||||||||||||||
new CustomEvent(`frames-loaded`, { | ||||||||||||||||||||||||||||||||||||
detail: { localId: localIdRef.current }, | ||||||||||||||||||||||||||||||||||||
}) | ||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||
if (data?.frames) frameDataRef.current = data.frames; | ||||||||||||||||||||||||||||||||||||
window.dispatchEvent( | ||||||||||||||||||||||||||||||||||||
new CustomEvent(FRAME_LOADED_EVENT, { | ||||||||||||||||||||||||||||||||||||
detail: { localId: localIdRef.current }, | ||||||||||||||||||||||||||||||||||||
}) | ||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||
Comment on lines
+28
to
+33
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Consider conditional event dispatch The event is currently dispatched regardless of whether frames data changed. Consider dispatching only when frames data is updated to avoid unnecessary events. useEffect(() => {
localIdRef.current = Math.random().toString(36).substring(7);
- if (data?.frames) frameDataRef.current = data.frames;
- window.dispatchEvent(
- new CustomEvent(FRAME_LOADED_EVENT, {
- detail: { localId: localIdRef.current },
- })
- );
+ if (data?.frames) {
+ frameDataRef.current = data.frames;
+ window.dispatchEvent(
+ new CustomEvent(FRAME_LOADED_EVENT, {
+ detail: { localId: localIdRef.current },
+ })
+ );
+ }
}, [data?.signature]); 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||
}, [data?.signature]); | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
const loadRange = React.useCallback( | ||||||||||||||||||||||||||||||||||||
|
@@ -44,15 +47,22 @@ export default function FrameLoaderView(props: ViewPropsType) { | |||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
return new Promise<void>((resolve) => { | ||||||||||||||||||||||||||||||||||||
window.addEventListener(`frames-loaded`, (e) => { | ||||||||||||||||||||||||||||||||||||
if ( | ||||||||||||||||||||||||||||||||||||
e instanceof CustomEvent && | ||||||||||||||||||||||||||||||||||||
e.detail.localId === localIdRef.current | ||||||||||||||||||||||||||||||||||||
) { | ||||||||||||||||||||||||||||||||||||
bufm.current.addNewRange(range); | ||||||||||||||||||||||||||||||||||||
resolve(); | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||
if (frameDataRef.current) { | ||||||||||||||||||||||||||||||||||||
bufm.current.addNewRange(range); | ||||||||||||||||||||||||||||||||||||
resolve(); | ||||||||||||||||||||||||||||||||||||
} else { | ||||||||||||||||||||||||||||||||||||
const onFramesLoaded = (e) => { | ||||||||||||||||||||||||||||||||||||
if ( | ||||||||||||||||||||||||||||||||||||
e instanceof CustomEvent && | ||||||||||||||||||||||||||||||||||||
e.detail.localId === localIdRef.current | ||||||||||||||||||||||||||||||||||||
) { | ||||||||||||||||||||||||||||||||||||
window.removeEventListener(FRAME_LOADED_EVENT, onFramesLoaded); | ||||||||||||||||||||||||||||||||||||
bufm.current.addNewRange(range); | ||||||||||||||||||||||||||||||||||||
resolve(); | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||||
window.addEventListener(FRAME_LOADED_EVENT, onFramesLoaded); | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
Comment on lines
+50
to
+65
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Improve type safety and cleanup handling The event handling logic looks good but could benefit from improved type safety and cleanup handling.
+type FrameLoadedEvent = CustomEvent<{ localId: string }>;
+const isFrameLoadedEvent = (e: Event): e is FrameLoadedEvent => {
+ return e instanceof CustomEvent && 'localId' in e.detail;
+};
const loadRange = React.useCallback(
async (range: BufferRange) => {
if (on_load_range) {
const unp = bufm.current.getUnprocessedBufferRange(range);
const isProcessed = unp === null;
if (!isProcessed) {
await triggerEvent(panelId, {
params: { range: unp },
operator: on_load_range,
});
}
return new Promise<void>((resolve) => {
if (frameDataRef.current) {
bufm.current.addNewRange(range);
resolve();
} else {
- const onFramesLoaded = (e) => {
- if (
- e instanceof CustomEvent &&
- e.detail.localId === localIdRef.current
- ) {
+ const onFramesLoaded = (e: Event) => {
+ if (isFrameLoadedEvent(e) && e.detail.localId === localIdRef.current) {
window.removeEventListener(FRAME_LOADED_EVENT, onFramesLoaded);
bufm.current.addNewRange(range);
resolve();
}
};
window.addEventListener(FRAME_LOADED_EVENT, onFramesLoaded);
}
});
}
},
[triggerEvent, on_load_range, localIdRef.current]
); Also, add cleanup in a useEffect: useEffect(() => {
return () => {
// Cleanup any pending event listeners on unmount
const cleanup = (e: Event) => {
if (isFrameLoadedEvent(e) && e.detail.localId === localIdRef.current) {
window.removeEventListener(FRAME_LOADED_EVENT, cleanup);
}
};
window.addEventListener(FRAME_LOADED_EVENT, cleanup);
};
}, []); |
||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,43 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import React, { useMemo } from "react"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { Timeline, useCreateTimeline, useTimeline } from "@fiftyone/playback"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { ViewPropsType } from "../utils/types"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const DEFAULT_CONFIG = { loop: false }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
export default function TimelineView(props: ViewPropsType) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const { schema } = props; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const { view = {} } = schema; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const { timeline_name, loop, total_frames } = view; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+7
to
+10
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Improve props type safety with specific destructuring The view object's shape should be explicitly typed for better type safety: +type TimelineViewData = {
+ timeline_name?: string;
+ loop?: boolean;
+ total_frames?: number;
+};
export default function TimelineView(props: ViewPropsType) {
const { schema } = props;
- const { view = {} } = schema;
+ const { view = {} as TimelineViewData } = schema;
const { timeline_name, loop, total_frames } = view; 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const providedConfig = { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
loop, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
totalFrames: total_frames, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const finalConfig = useMemo( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
() => ({ ...DEFAULT_CONFIG, ...providedConfig }), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
[providedConfig] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (!timeline_name) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
throw new Error("Timeline name is required"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (!finalConfig.totalFrames) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
throw new Error("Total frames is required"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+21
to
+26
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Enhance error handling with descriptive messages The error messages should be more descriptive and include available context. Also, consider wrapping the component in an error boundary. - throw new Error("Timeline name is required");
+ throw new Error("TimelineView: timeline_name is required in the view configuration");
- throw new Error("Total frames is required");
+ throw new Error(`TimelineView: totalFrames is required in the configuration for timeline "${timeline_name}"`); Consider implementing an error boundary: class TimelineErrorBoundary extends React.Component<{ children: React.ReactNode }> {
componentDidCatch(error: Error) {
console.error("Timeline failed to render:", error);
// Add your error reporting logic here
}
render() {
return this.props.children;
}
} |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return <TimelineCreator timelineName={timeline_name} {...finalConfig} />; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
export const TimelineCreator = ({ timelineName, totalFrames, loop }) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const config = useMemo(() => ({ totalFrames, loop }), [totalFrames, loop]); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const { isTimelineInitialized } = useCreateTimeline({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
name: timelineName, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
config, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (!isTimelineInitialized) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return null; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return <Timeline name={timelineName} />; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+31
to
+43
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add prop types and improve error handling for TimelineCreator The component needs proper TypeScript types and better error/loading state handling: -export const TimelineCreator = ({ timelineName, totalFrames, loop }) => {
+type TimelineCreatorProps = {
+ timelineName: string;
+ totalFrames: number;
+ loop: boolean;
+};
+export const TimelineCreator: React.FC<TimelineCreatorProps> = ({
+ timelineName,
+ totalFrames,
+ loop,
+}) => {
const config = useMemo(() => ({ totalFrames, loop }), [totalFrames, loop]);
- const { isTimelineInitialized } = useCreateTimeline({
+ const { isTimelineInitialized, error } = useCreateTimeline({
name: timelineName,
config,
});
+ if (error) {
+ throw new Error(`Failed to initialize timeline: ${error.message}`);
+ }
if (!isTimelineInitialized) {
- return null;
+ return <div>Initializing timeline...</div>;
}
return <Timeline name={timelineName} />;
}; 📝 Committable suggestion
Suggested change
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,19 @@ | ||
import { fixupConfigRules } from "@eslint/compat"; | ||
import hooksPlugin from "eslint-plugin-react-hooks"; | ||
import pluginReactConfig from "eslint-plugin-react/configs/recommended.js"; | ||
import globals from "globals"; | ||
import tseslint from "typescript-eslint"; | ||
import pluginReactConfig from "eslint-plugin-react/configs/recommended.js"; | ||
import { fixupConfigRules } from "@eslint/compat"; | ||
|
||
export default [ | ||
{ files: ["lib/**/*.{js,mjs,cjs,ts,jsx,tsx}"] }, | ||
{ languageOptions: { parserOptions: { ecmaFeatures: { jsx: true } } } }, | ||
{ languageOptions: { globals: globals.browser } }, | ||
...tseslint.configs.recommended, | ||
...fixupConfigRules(pluginReactConfig), | ||
{ | ||
plugins: { | ||
"react-hooks": hooksPlugin, | ||
}, | ||
rules: hooksPlugin.configs.recommended.rules, | ||
}, | ||
]; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -26,14 +26,16 @@ interface TimelineProps { | |
*/ | ||
export const Timeline = React.memo( | ||
React.forwardRef<HTMLDivElement, TimelineProps>( | ||
({ name, style, controlsStyle }, ref) => { | ||
(timelineProps: TimelineProps, ref) => { | ||
const { name, style, controlsStyle } = timelineProps; | ||
|
||
const { playHeadState, config, play, pause, setSpeed } = | ||
useTimeline(name); | ||
const frameNumber = useFrameNumber(name); | ||
|
||
const { getSeekValue, seekTo } = useTimelineVizUtils(); | ||
const { getSeekValue, seekTo } = useTimelineVizUtils(name); | ||
|
||
const seekBarValue = React.useMemo(() => getSeekValue(), [frameNumber]); | ||
const seekBarValue = React.useMemo(() => getSeekValue(), [getSeekValue]); | ||
Comment on lines
+36
to
+38
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Codebase verification Memoization dependencies are incomplete The const seekBarValue = React.useMemo(() => getSeekValue(), [getSeekValue, frameNumber, config.totalFrames]); 🔗 Analysis chainVerify seekBarValue memoization dependencies The memoization depends only on Let me gather more information about the implementation of useTimelineVizUtils to understand the dependencies. Let me check the complete implementation of getSeekValue and its dependencies in useTimelineVizUtils. 🏁 Scripts executedThe following scripts were executed for the analysis: Script: #!/bin/bash
# Search for references to getSeekValue to understand its dependencies
ast-grep --pattern 'const { $$$, getSeekValue, $$$ } = useTimelineVizUtils($$$)'
Length of output: 196 Script: #!/bin/bash
# Search for useTimelineVizUtils implementation
ast-grep --pattern 'function useTimelineVizUtils($_) {
$$$
}'
# Also search for any file containing useTimelineVizUtils
rg "useTimelineVizUtils" -A 10
Length of output: 2753 Script: #!/bin/bash
# Get the complete implementation of useTimelineVizUtils
rg -A 30 "export const useTimelineVizUtils = \(name\?: TimelineName\)" app/packages/playback/src/lib/use-timeline-viz-utils.ts
Length of output: 1019 |
||
|
||
const { loaded, loading } = useTimelineBuffers(name); | ||
|
||
|
@@ -52,15 +54,15 @@ export const Timeline = React.memo( | |
detail: { timelineName: name, start: true }, | ||
}) | ||
); | ||
}, [pause]); | ||
}, [pause, name]); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Consider improving event handling type safety While the event handling works correctly, consider these improvements for better maintainability: +// At the top of the file
+interface SeekEventDetail {
+ timelineName: TimelineName;
+ start: boolean;
+}
+
+const SEEK_EVENT = 'seek';
+
const onSeekStart = React.useCallback(() => {
pause();
dispatchEvent(
- new CustomEvent("seek", {
+ new CustomEvent<SeekEventDetail>(SEEK_EVENT, {
detail: { timelineName: name, start: true },
})
);
}, [pause, name]); Also applies to: 65-65 |
||
|
||
const onSeekEnd = React.useCallback(() => { | ||
dispatchEvent( | ||
new CustomEvent("seek", { | ||
detail: { timelineName: name, start: false }, | ||
}) | ||
); | ||
}, []); | ||
}, [name]); | ||
|
||
const [isHoveringSeekBar, setIsHoveringSeekBar] = React.useState(false); | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
/source/user_guide/model_zoo/models.rst | ||
/source/model_zoo/models.rst |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove unused lodash import
The
has
function from lodash is imported but never used in the code. This unnecessary import should be removed to maintain a clean codebase and optimize bundle size.-import { has } from "lodash";
📝 Committable suggestion