-
Notifications
You must be signed in to change notification settings - Fork 593
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
Cherry picks for release/v1.0.1 #4896
Conversation
* add dynamic embedded document field type for rrd files * add schema utils to work with embedded doc type fields * add versioned renderer with url+metadata support * remove explicit version
* organizing * rm Tmp * cleanup * add example back * cleaning * useKeyEvents hook * after load handling * fix import * enable timeline * default to true * refreshers
WalkthroughThe pull request introduces significant modifications across multiple components related to video playback and looker functionality. Key changes include the refactoring of the Changes
Possibly related PRs
Suggested reviewers
Poem
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
Documentation and Community
|
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.
🔥
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.
Actionable comments posted: 12
🧹 Outside diff range and nitpick comments (20)
app/packages/looker/src/index.ts (1)
6-6
: LGTM! Consider grouping related exports.The addition of
getFrameNumber
to the exports is correct and follows TypeScript best practices. This change aligns with the PR objectives for cherry-picking specific changes.For improved readability and maintainability, consider grouping related exports from the same module. You could move this line next to other exports from
./elements/util
if there are any, or consider creating a separate export statement for utility functions if this becomes a pattern.fiftyone/utils/rerun.py (1)
14-22
: Enhance the class docstring for better clarity.The class docstring provides useful information, but it could be improved for better clarity and consistency with Python documentation standards.
Consider updating the docstring as follows:
class RrdFile(DynamicEmbeddedDocument, fol._HasMedia): """Class for storing a rerun data (rrd) file and its associated metadata. Attributes: filepath (str): The path to the rrd file. version (str): The version of the rrd file. """This change:
- Uses "Attributes" instead of "Args" since these are class attributes.
- Specifies the types of the attributes (str).
- Capitalizes the attribute descriptions for consistency.
app/packages/utilities/src/schema.ts (2)
55-74
: LGTM! Consider a minor readability improvement.The implementation of
getFieldsWithEmbeddedDocType
is correct and efficient. It properly traverses the schema recursively and collects fields with the specifiedembeddedDocType
.For improved readability, consider using the
Array.prototype.push
method with spread syntax to add all matching fields at once:function recurse(schema: Schema) { - for (const field of Object.values(schema ?? {})) { - if (field.embeddedDocType === embeddedDocType) { - result.push(field); - } + result.push(...Object.values(schema ?? {}).filter(field => field.embeddedDocType === embeddedDocType)); + for (const field of Object.values(schema ?? {})) { if (field.fields) { recurse(field.fields); } } }This change would make the code more concise and potentially more efficient by reducing the number of array mutations.
76-93
: LGTM! Consider simplifying the recursive function.The implementation of
doesSchemaContainEmbeddedDocType
is correct and efficient. It properly traverses the schema recursively and short-circuits when a matchingembeddedDocType
is found.Consider simplifying the recursive function for improved readability:
export function doesSchemaContainEmbeddedDocType( schema: Schema, embeddedDocType: string ): boolean { - function recurse(schema: Schema): boolean { - return Object.values(schema ?? {}).some((field) => { - if (field.embeddedDocType === embeddedDocType) { - return true; - } - if (field.fields) { - return recurse(field.fields); - } - return false; - }); - } + const recurse = (schema: Schema): boolean => + Object.values(schema ?? {}).some( + (field) => + field.embeddedDocType === embeddedDocType || + (field.fields && recurse(field.fields)) + ); return recurse(schema); }This refactored version:
- Uses an arrow function for conciseness.
- Simplifies the logic by combining conditions.
- Eliminates the need for explicit
return
statements.The resulting code is more readable and maintains the same functionality and efficiency.
app/packages/core/src/components/Modal/hooks.ts (1)
22-41
: Good implementation, but type safety can be improvedThe
useLookerOptionsUpdate
hook is well-implemented using Recoil patterns. However, there are a few improvements we can make:
- Replace the
{}
type with a more specific type for better type safety.- Add JSDoc comments to improve documentation.
Here's a suggested refactor:
/** * Options for the Looker component */ type LookerOptions = { // Define the structure of your options here // For example: // showJSON?: boolean; // showHelp?: boolean; // Add other properties as needed }; /** * Hook to update Looker options * @returns A function to update Looker options */ export const useLookerOptionsUpdate = () => { return useRecoilCallback( ({ snapshot, set }) => async (update: Partial<LookerOptions>, updater?: (updated: LookerOptions) => void) => { const currentOptions = await snapshot.getPromise( fos.savedLookerOptions ); const panels = await snapshot.getPromise(fos.lookerPanels); const updated: LookerOptions = { ...currentOptions, ...update, showJSON: panels.json.isOpen, showHelp: panels.help.isOpen, }; set(fos.savedLookerOptions, updated); if (updater) updater(updated); } ); };This refactor:
- Introduces a
LookerOptions
type for better type safety.- Uses
Partial<LookerOptions>
for theupdate
parameter to allow partial updates.- Adds JSDoc comments for better documentation.
Please adjust the
LookerOptions
type to match your actual options structure.🧰 Tools
🪛 Biome
[error] 25-25: Don't use '{}' as a type.
Prefer explicitly define the object shape. '{}' means "any non-nullable value".
(lint/complexity/noBannedTypes)
app/packages/looker/src/elements/common/looker.ts (2)
29-33
: Improved state destructuring in keydown event handlerThe changes to the state destructuring in the keydown event handler are good:
- Accessing
shouldHandleKeyEvents
throughoptions
reflects an update in the state structure, improving consistency.- The destructuring is clear and follows TypeScript best practices.
To further enhance readability, consider using an interface or type for the state shape:
interface LookerState extends BaseState { SHORTCUTS: Record<string, Control>; error: boolean; options: { shouldHandleKeyEvents: boolean; }; }This would make the state structure more explicit and self-documenting.
52-52
: Consistent state destructuring in keyup event handlerThe change to the state destructuring in the keyup event handler is good and consistent with the keydown handler. This maintains a uniform approach to accessing state properties across different event handlers.
For improved consistency with the keydown handler and better readability, consider using multi-line destructuring:
update(({ SHORTCUTS, error, options: { shouldHandleKeyEvents } }) => { // ... rest of the function });This format aligns with the keydown handler and makes the destructured properties easier to read at a glance.
e2e-pw/src/oss/poms/modal/imavid-controls.ts (1)
35-42
: Approve implementation with a suggestion for timeoutThe
waitUntilBufferingIsFinished
method is well-implemented and follows good E2E testing practices by using data attributes. However, consider adding a timeout to prevent potential infinite waiting.Consider modifying the method to include a timeout:
private async waitUntilBufferingIsFinished(timeout = 30000) { await this.page.waitForFunction( () => document .querySelector("[data-cy=imavid-playhead]") ?.getAttribute("data-playhead-state") !== "buffering", { timeout } ); }This change allows for a configurable timeout and prevents the test from hanging indefinitely if buffering doesn't complete.
app/packages/state/src/recoil/modal.ts (1)
1-1
: LGTM! Consider grouping related imports.The changes to the import statements look good. Removing unused imports and adding the necessary
Lookers
type improves code cleanliness.Consider grouping related imports together. For example, you could move the
Lookers
import next to other imports from "@fiftyone/looker" for better organization:import { PointInfo, type Sample } from "@fiftyone/looker"; import type { Lookers } from "../hooks";Also applies to: 6-6
app/packages/state/src/hooks/useCreateLooker.ts (2)
39-40
: New optional parameter added for enhanced flexibilityThe addition of the
enableTimeline
optional parameter is a good enhancement, providing more control over the looker instance configuration. This change maintains backward compatibility while extending functionality.Consider adding a JSDoc comment to describe the purpose and expected values of the
enableTimeline
parameter. This would improve the function's documentation and help other developers understand its usage.
116-116
: Enhanced configuration options for looker instanceThe addition of
enableTimeline
andshouldHandleKeyEvents
properties to theconfig
object enhances the flexibility and control over the looker instance. These changes are consistent with the function signature update and provide logical configuration options.For consistency, consider grouping related configuration properties together. You might want to move the
shouldHandleKeyEvents
property closer to theenableTimeline
property in theconfig
object, as they both relate to user interaction settings.Also applies to: 137-137
app/packages/core/src/components/Modal/ImaVidLooker.tsx (4)
20-26
: Improved import organizationThe refactoring of imports enhances code organization by moving hooks to a separate file. This is a good practice for maintainability and readability.
Consider grouping related imports together. For example, you could group all hooks imports:
import { useClearSelectedLabels, useShowOverlays, useInitializeImaVidSubscriptions, useModalContext, } from "./hooks"; import useKeyEvents from "./use-key-events";
136-136
: Effective use of custom hooksThe introduction of the
useKeyEvents
hook simplifies the component's logic by encapsulating key event handling. This aligns with React best practices for code organization and reusability.Consider adding a comment explaining the purpose of the
useKeyEvents
hook for better code documentation:// Handle keyboard events for navigation and interaction within the looker useKeyEvents(initialRef, sample._id, looker);
Line range hint
36-364
: Consider component decomposition for improved maintainabilityThe
ImaVidLookerReact
component is well-structured but quite complex. To enhance maintainability and readability, consider breaking it down into smaller, more focused components. For example:
- Extract the timeline-related logic into a separate
TimelineManager
component.- Create a
FrameRenderer
component to handle frame rendering and buffering.- Move the event handling logic into a custom hook, e.g.,
useLookerEvents
.This decomposition would make the code easier to understand, test, and maintain.
Would you like assistance in creating a plan for this refactoring?
Line range hint
36-364
: Enhance TypeScript usage for improved type safetyWhile the component effectively uses TypeScript, there are opportunities to improve type safety:
- Replace type assertions like
as ImaVidLooker
with proper type guards or generics where possible.- Consider using more specific types for event handlers, e.g.,
React.MouseEvent<HTMLDivElement>
instead of justEvent
.- Explicitly type the return value of functions and methods, especially for complex objects.
Example improvement:
// Before const handleError = useErrorHandler(); useEventHandler(looker, "error", (event) => handleError(event.detail)); // After const handleError = useErrorHandler(); useEventHandler(looker, "error", (event: CustomEvent<Error>) => handleError(event.detail));These changes will enhance type safety and make the code more self-documenting.
Would you like assistance in implementing these TypeScript improvements?
app/packages/looker/src/state.ts (1)
178-178
: LGTM with a minor suggestion.The addition of
shouldHandleKeyEvents
as an optional boolean property to theBaseOptions
interface is a good improvement. It allows for more granular control over key event handling while maintaining backward compatibility.Consider adding a brief JSDoc comment to explain the purpose and default behavior of this property. For example:
/** * Whether key events should be handled. If not set, defaults to true. */ shouldHandleKeyEvents?: boolean;fiftyone/server/metadata.py (1)
Line range hint
27-37
: Suggestion: Add documentation for RrdFile integrationThe changes to add support for
RrdFile
look good. However, it would be beneficial to add a brief comment or documentation explaining the purpose ofRrdFile
and its role in the metadata handling system. This would help other developers understand the rationale behind these changes and howRrdFile
fits into the larger picture.Consider adding a comment above the
_ADDITIONAL_MEDIA_FIELDS
dictionary or updating the module's docstring to include information aboutRrdFile
.app/packages/core/src/components/Modal/use-key-events.ts (2)
7-12
: Consistent Naming Convention for Recoil SelectorsThe
hoveredSampleId
selector is well-defined. For better maintainability and consistency, consider following a naming convention that distinguishes selectors from atoms, such as prefixing withselect
or suffixing withSelector
.
14-18
: Name the Default Exported Function for Better DebuggingThe anonymous default export can make debugging more difficult since stack traces may not display a function name. Consider naming the function to enhance readability and debugging.
Apply this change:
-export default function ( +export default function useKeyEvents(app/packages/core/src/components/Modal/VideoLooker.tsx (1)
38-38
: Reevaluate inclusion ofdata-cy
attribute in productionThe
data-cy
attribute is typically used for end-to-end testing with tools like Cypress. Consider whether it should be included in production code or if it can be conditionally added during testing builds.
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
⛔ Files ignored due to path filters (2)
app/packages/looker/package.json
is excluded by!**/*.json
app/yarn.lock
is excluded by!**/yarn.lock
,!**/*.lock
,!**/*.lock
📒 Files selected for processing (21)
- app/packages/core/src/components/Modal/ImaVidLooker.tsx (2 hunks)
- app/packages/core/src/components/Modal/ModalLooker.tsx (3 hunks)
- app/packages/core/src/components/Modal/VideoLooker.tsx (1 hunks)
- app/packages/core/src/components/Modal/hooks.ts (1 hunks)
- app/packages/core/src/components/Modal/use-key-events.ts (1 hunks)
- app/packages/core/src/components/Modal/use-looker.ts (1 hunks)
- app/packages/core/src/components/Modal/utils.ts (1 hunks)
- app/packages/looker/src/elements/base.ts (1 hunks)
- app/packages/looker/src/elements/common/looker.ts (3 hunks)
- app/packages/looker/src/index.ts (1 hunks)
- app/packages/looker/src/lookers/imavid/index.ts (1 hunks)
- app/packages/looker/src/lookers/video.ts (3 hunks)
- app/packages/looker/src/state.ts (3 hunks)
- app/packages/state/src/hooks/useCreateLooker.ts (4 hunks)
- app/packages/state/src/recoil/modal.ts (3 hunks)
- app/packages/state/src/utils.ts (2 hunks)
- app/packages/utilities/src/schema.test.ts (7 hunks)
- app/packages/utilities/src/schema.ts (1 hunks)
- e2e-pw/src/oss/poms/modal/imavid-controls.ts (1 hunks)
- fiftyone/server/metadata.py (2 hunks)
- fiftyone/utils/rerun.py (1 hunks)
🧰 Additional context used
📓 Path-based instructions (19)
app/packages/core/src/components/Modal/ImaVidLooker.tsx (1)
Pattern
**/*.{ts,tsx}
: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.app/packages/core/src/components/Modal/ModalLooker.tsx (1)
Pattern
**/*.{ts,tsx}
: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.app/packages/core/src/components/Modal/VideoLooker.tsx (1)
Pattern
**/*.{ts,tsx}
: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.app/packages/core/src/components/Modal/hooks.ts (1)
Pattern
**/*.{ts,tsx}
: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.app/packages/core/src/components/Modal/use-key-events.ts (1)
Pattern
**/*.{ts,tsx}
: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.app/packages/core/src/components/Modal/use-looker.ts (1)
Pattern
**/*.{ts,tsx}
: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.app/packages/core/src/components/Modal/utils.ts (1)
Pattern
**/*.{ts,tsx}
: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.app/packages/looker/src/elements/base.ts (1)
Pattern
**/*.{ts,tsx}
: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.app/packages/looker/src/elements/common/looker.ts (1)
Pattern
**/*.{ts,tsx}
: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.app/packages/looker/src/index.ts (1)
Pattern
**/*.{ts,tsx}
: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.app/packages/looker/src/lookers/imavid/index.ts (1)
Pattern
**/*.{ts,tsx}
: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.app/packages/looker/src/lookers/video.ts (1)
Pattern
**/*.{ts,tsx}
: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.app/packages/looker/src/state.ts (1)
Pattern
**/*.{ts,tsx}
: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.app/packages/state/src/hooks/useCreateLooker.ts (1)
Pattern
**/*.{ts,tsx}
: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.app/packages/state/src/recoil/modal.ts (1)
Pattern
**/*.{ts,tsx}
: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.app/packages/state/src/utils.ts (1)
Pattern
**/*.{ts,tsx}
: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.app/packages/utilities/src/schema.test.ts (1)
Pattern
**/*.{ts,tsx}
: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.app/packages/utilities/src/schema.ts (1)
Pattern
**/*.{ts,tsx}
: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.e2e-pw/src/oss/poms/modal/imavid-controls.ts (1)
Pattern
**/*.{ts,tsx}
: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.
🪛 Biome
app/packages/core/src/components/Modal/hooks.ts
[error] 25-25: Don't use '{}' as a type.
Prefer explicitly define the object shape. '{}' means "any non-nullable value".
(lint/complexity/noBannedTypes)
🔇 Additional comments (36)
fiftyone/utils/rerun.py (3)
1-11
: LGTM: File structure and imports are appropriate.The file structure is well-organized with a clear module docstring, copyright information, and relevant imports from the fiftyone package. This sets up the file correctly for the implementation of Rerun utilities.
24-25
: LGTM: Class attributes are well-defined.The
filepath
andversion
attributes are appropriately defined asStringField
s, which is suitable for storing the path to the rrd file and its version, respectively.
1-25
: Overall assessment: Well-implemented new utility for Rerun integration.This new file introduces a concise and focused implementation for handling Rerun data files. The
RrdFile
class is well-structured and provides the necessary attributes for storing rrd file information. The implementation aligns with the PR objectives and seems appropriate for the intended purpose.Minor improvements to the docstring have been suggested, but overall, the code is of good quality and ready for integration into the release.
app/packages/looker/src/elements/base.ts (1)
67-67
: Improved null checking with optional chainingThe change from
this.element &&
tothis.element?.
is a good improvement. It uses the optional chaining operator, which is a more modern and expressive way to handle potentially null or undefined values. This change maintains the same functionality while making the code more concise and aligned with TypeScript best practices.app/packages/looker/src/elements/common/looker.ts (1)
6-9
: Improved import statementsThe changes to the import statements are beneficial:
- Using
import type
forBaseState
,Control
, andEvents
is a TypeScript best practice for type-only imports. This can lead to better performance and clearer code intentions.- Separating the
ControlEventKeyType
import allows for more granular control over what's being imported, potentially reducing bundle size.These changes align well with TypeScript best practices and should be maintained.
e2e-pw/src/oss/poms/modal/imavid-controls.ts (2)
45-50
: Approve changes totogglePlay
methodThe addition of
waitUntilBufferingIsFinished
at the beginning of thetogglePlay
method is a good improvement. It ensures that the play/pause action only occurs after buffering is complete, which should increase the reliability of the test.The blank line added after the new method call improves readability by clearly separating the new buffering check from the existing logic.
Line range hint
1-150
: Summary of changesThe changes in this file improve the reliability of video playback control in E2E tests by introducing a method to wait for buffering to complete before toggling play/pause. The implementation follows TypeScript and Playwright best practices, and aligns well with the PR objectives of cherry-picking specific changes for a release.
These modifications enhance the robustness of the E2E tests without introducing significant complexity, which is beneficial for maintaining test stability in the release branch.
app/packages/state/src/utils.ts (1)
21-21
: LGTM: Import statement updated correctlyThe addition of
ModalSample
to the import statement is consistent with its usage in the updated function signature. This change enhances type safety and improves code clarity.app/packages/looker/src/lookers/imavid/index.ts (1)
18-18
: LGTM. Verify the intentionality of the new export.The addition of this export statement looks good. It makes
BUFFERING_PAUSE_TIMEOUT
available to other modules that import from this file.To ensure this change is intentional and doesn't introduce any unintended side effects, please run the following script:
app/packages/state/src/recoil/modal.ts (2)
72-72
: LGTM! Good use of optional chaining.The change from
if (id && id.endsWith("-modal"))
toif (id?.endsWith("-modal"))
is a good improvement. Using optional chaining (?.
) is a safer approach as it handles cases whereid
might beundefined
ornull
more gracefully, reducing the risk of runtime errors.
26-26
: LGTM! Please provide documentation for the Lookers type.The change from
AbstractLooker<BaseState> | null
toLookers | null
looks good and aligns with the import changes. This suggests a more specific type for the modalLooker state.Could you please provide documentation for the
Lookers
type? This will help maintain clarity about what this type represents. You can run the following command to check if theLookers
type is documented:app/packages/state/src/hooks/useCreateLooker.ts (1)
12-12
: Improved type import for better code organizationThe change to import
BaseState
andImaVidConfig
as types is a good practice in TypeScript. It clearly separates runtime dependencies from type-only imports, which can lead to better code organization and potentially smaller bundle sizes after compilation.app/packages/core/src/components/Modal/ImaVidLooker.tsx (1)
Line range hint
1-364
: Overall assessment: Well-structured component with room for minor improvementsThe
ImaVidLookerReact
component is well-implemented and follows many React and TypeScript best practices. The recent changes have improved code organization and simplified some logic. To further enhance the code:
- Consider decomposing the component into smaller, more focused parts.
- Improve TypeScript usage for better type safety.
- Add more inline documentation for complex logic.
- Group related imports for better readability.
These suggestions will help maintain the code's quality as it evolves and make it easier for other developers to understand and work with the component.
app/packages/looker/src/state.ts (2)
462-462
: LGTM!The addition of
shouldHandleKeyEvents: true
toDEFAULT_BASE_OPTIONS
is appropriate. It ensures that the default behavior remains unchanged (handling key events), while still allowing for this behavior to be overridden when needed.This change aligns well with the addition of the
shouldHandleKeyEvents
property to theBaseOptions
interface and maintains consistency in the codebase.
222-222
: Approve with a compatibility concern.The addition of
enableTimeline: boolean
to theVideoConfig
interface is a good feature that allows control over timeline visibility in video configurations.However, as this is a required property, it may break existing code that doesn't provide this value. Consider the following options:
- Make it optional (
enableTimeline?: boolean
) to maintain backward compatibility.- If it must be required, ensure all existing
VideoConfig
usages are updated accordingly.To verify the impact, please run the following script:
This will help identify areas that might need attention due to this change.
fiftyone/server/metadata.py (2)
27-27
: LGTM: Import statement for RrdFileThe import statement for
RrdFile
fromfiftyone.utils.rerun
is correctly added. This import is necessary for the subsequent usage in_ADDITIONAL_MEDIA_FIELDS
.
37-37
: LGTM: Addition of RrdFile to _ADDITIONAL_MEDIA_FIELDSThe addition of
RrdFile: "filepath"
to_ADDITIONAL_MEDIA_FIELDS
is correct and consistent with other entries. This change extends the metadata handling capabilities to includeRrdFile
.To ensure this change is properly integrated, please verify its usage with the following script:
✅ Verification successful
Verified:
RrdFile
Addition to_ADDITIONAL_MEDIA_FIELDS
The addition of
RrdFile: "filepath"
to_ADDITIONAL_MEDIA_FIELDS
has been successfully integrated and utilized across the codebase without any issues.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify the usage of RrdFile in metadata handling # Search for usages of _ADDITIONAL_MEDIA_FIELDS echo "Searching for usages of _ADDITIONAL_MEDIA_FIELDS:" rg "_ADDITIONAL_MEDIA_FIELDS" --type python # Search for usages of RrdFile echo "\nSearching for usages of RrdFile:" rg "RrdFile" --type python # Search for functions that might need updating due to this change echo "\nSearching for potential functions that might need updating:" rg "def get_metadata|def read_metadata|def _create_media_urls|def _get_additional_media_fields" --type pythonLength of output: 596
Script:
#!/bin/bash # Description: Verify the usage of RrdFile in metadata handling without relying on --type python # Find all Python files and search for _ADDITIONAL_MEDIA_FIELDS echo "Searching for usages of _ADDITIONAL_MEDIA_FIELDS in Python files:" fd --extension py --type f | xargs rg "_ADDITIONAL_MEDIA_FIELDS" # Find all Python files and search for RrdFile echo "\nSearching for usages of RrdFile in Python files:" fd --extension py --type f | xargs rg "RrdFile" # Find all Python files and search for specific function definitions that might need updating echo "\nSearching for potential functions that might need updating in Python files:" fd --extension py --type f | xargs rg "def (get_metadata|read_metadata|_create_media_urls|_get_additional_media_fields)"Length of output: 1529
app/packages/core/src/components/Modal/VideoLooker.tsx (3)
13-15
: Clarify the usage ofsample
prop andsample
fromuseLooker
It appears that
sample
is being passed as a prop and also retrieved fromuseLooker
. Please verify whether passingsample
as a prop is necessary if it can be obtained fromuseLooker
, or if there's a redundancy.Also applies to: 19-19
76-77
: Verify event handler attachment withfos.useEventHandler
Ensure that using
fos.useEventHandler
to attachpause
andplay
event handlers tolooker
is correct and aligns with the intended use of the API.
28-28
:⚠️ Potential issueVerify parameters passed to
getFrameNumber
You're passing
duration
as both thecurrentTime
andduration
parameters ingetFrameNumber(duration, duration, frameRate)
. Please verify if this is intentional. If the goal is to calculate the total number of frames, ensure that the parameters align with the function's expected inputs.app/packages/core/src/components/Modal/ModalLooker.tsx (3)
30-60
: Implementation ofModalLookerNoTimeline
is correctThe
ModalLookerNoTimeline
component is properly implemented. It correctly utilizes theuseLooker
hook and manages state withuseEffect
. The props and Recoil states are used appropriately, and the component follows React and Recoil best practices.
80-80
: Verify conditional rendering logic for potential overlapThe conditional rendering checks for
shouldRenderImavid
andvideo
to determine which component to render. Please ensure that there are no scenarios where bothshouldRenderImavid
andvideo
could be true simultaneously, which might lead to unintended component rendering or unexpected behavior.Consider reviewing the conditions or adding safeguards to handle cases where both conditions might be true.
Also applies to: 86-89
27-27
:⚠️ Potential issueEnsure all usages of
LookerProps
provide the requiredsample
propertyThe
sample
property inLookerProps
has been changed from optional to required. Please make sure that all components and functions usingLookerProps
are updated to provide thesample
property to prevent potential type errors or runtime issues.Run the following script to find all usages of
LookerProps
and check if thesample
prop is provided:✅ Verification successful
Verified: All usages of
LookerProps
provide the requiredsample
property.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Find all components or functions using `LookerProps` and verify they include the 'sample' prop. # Search for all TypeScript files that reference 'LookerProps' rg --type-add 'typescript:*.{ts,tsx}' --type typescript 'LookerProps' -l | xargs -I {} sh -c ' echo "Checking {}" # Check if "sample" is provided in the props or used within the component if ! rg "sample" {}; then echo "Warning: 'sample' prop may be missing in {}" fi 'Length of output: 614
app/packages/core/src/components/Modal/use-looker.ts (5)
43-48
: Confirm event handlers are properly cleaned upWhen using
fos.useEventHandler
to attach event handlers, it's important to ensure that these handlers are correctly removed when the component unmounts or when dependencies change to prevent memory leaks or unintended behaviors. Verify thatfos.useEventHandler
handles cleanup internally.You might want to check similar usages or documentation to confirm this.
104-104
: Ensure all necessary dependencies are passed touseKeyEvents
When invoking
useKeyEvents
, confirm that all required dependencies are provided. Specifically, verify thatinitialRef
,sample.sample._id
, andlooker
are sufficient for the hook to function correctly without missing any necessary context.
13-107
: Good use of custom hook and state managementThe
useLooker
hook is well-structured, effectively managing state, refs, and side effects. It demonstrates good practices in custom hook creation, event handling, and integration with external libraries like Recoil and React Error Boundary.
1-12
: Imports are organized and follow conventionsThe import statements are correctly organized, importing necessary modules and hooks from React, Recoil, and other local modules. This aligns with the project's coding guidelines for import organization.
76-78
: Verify cleanup logic inuseEffect
The cleanup function in this
useEffect
depends onlooker
. This means that whenever thelooker
instance changes, the previous instance will be destroyed. Ensure that this behavior is intentional and that re-creating and destroyinglooker
instances as dependencies change won't lead to performance issues or unintended side effects.To confirm that this is the desired behavior, you can run the following script to check how often
looker
is re-created:app/packages/utilities/src/schema.test.ts (6)
22-22
: Update Reflects Correct Field Naming and PathsThe changes to the
name
andpath
properties in theembedded
schema correctly reflect the structure of the embedded fields. This improves clarity and consistency within the schema definition.Also applies to: 33-33
45-45
: Consistent Naming and Path Updates for Embedded Fields with Database FieldsThe updates to the
name
andpath
properties forembeddedWithDbFields
and its nested fieldsample_id
maintain consistency in the schema, especially where database fields (dbField
) are involved. This ensures that the schema accurately represents the underlying data structure.Also applies to: 57-57
92-92
: Ensure Non-Null Assertion onfields
is SafeThe use of the non-null assertion operator
!
onSCHEMA.embedded.fields
assumes thatfields
is always defined. Verify thatfields
is indeed always present to prevent potential runtime errors due to undefined values.
113-144
: New Test Suite Enhances Coverage forgetFieldsWithEmbeddedDocType
The addition of the
describe
block forgetFieldsWithEmbeddedDocType
significantly enhances test coverage. The tests effectively verify:
- Retrieval of fields with a specific
embeddedDocType
at the top level.- Retrieval of fields with a specific
embeddedDocType
within nested fields.- Correct handling when the specified
embeddedDocType
does not exist.- Behavior with an empty schema.
These tests improve confidence in the function's correctness across various scenarios.
146-176
: Comprehensive Tests Added fordoesSchemaContainEmbeddedDocType
The new test cases for
doesSchemaContainEmbeddedDocType
thoroughly validate the function's behavior by checking:
- Detection of
embeddedDocType
at the top level.- Detection of
embeddedDocType
within nested fields.- Correct response when the
embeddedDocType
does not exist.- Functionality with an empty schema.
This comprehensive testing ensures that any changes to the schema will be accurately reflected in the presence checks for embedded document types.
92-92
: Verification offields
Presence in SchemaTo ensure that the non-null assertion on
fields
does not cause runtime errors, you can verify the presence offields
in the schema definitions.Run the following script to check for any schema entries where
fields
might be undefined:Ensure that
schema.json
contains your schema object for this test. If the script returns no results, it confirms that all schema entries havefields
defined.app/packages/looker/src/lookers/video.ts (2)
23-25
: Imports added appropriatelyThe added imports of
setFrameNumberAtom
andgetDefaultStore
are necessary for the new timeline and state management functionality.
530-535
: Timeline state synchronization implemented correctlyThe code correctly updates the frame number atom when the timeline feature is enabled, ensuring synchronization between the video looker's frame number and the global state.
export function shortcutToHelpItems(SHORTCUTS) { | ||
const result = {}; | ||
for (const k of SHORTCUTS) { | ||
result[SHORTCUTS[k].shortcut] = SHORTCUTS[k]; | ||
} | ||
return Object.values(result); | ||
} |
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.
💡 Codebase verification
Ensure changes to shortcutToHelpItems
are reflected in all usages
The function shortcutToHelpItems
is used in the following files:
app/packages/core/src/components/Modal/utils.ts
app/packages/core/src/components/Modal/use-looker.ts
app/packages/core/src/components/Modal/ImaVidLooker.tsx
Please make sure that any modifications to shortcutToHelpItems
are compatible with these implementations to prevent introducing issues.
🔗 Analysis chain
Improve type safety and function implementation
The function shortcutToHelpItems
has several areas for improvement:
- Add type annotations to enhance type safety.
- Clarify the expected structure of the
SHORTCUTS
parameter. - Use a more descriptive function name.
- Build the result as an array directly for better performance.
- Use lowercase for the parameter name as it's not a constant.
Here's a suggested implementation with these improvements:
interface ShortcutItem {
shortcut: string;
[key: string]: any;
}
export function getUniqueShortcutItems(shortcuts: Record<string, ShortcutItem>): ShortcutItem[] {
const uniqueShortcuts = new Map<string, ShortcutItem>();
for (const item of Object.values(shortcuts)) {
if (item.shortcut) {
uniqueShortcuts.set(item.shortcut, item);
}
}
return Array.from(uniqueShortcuts.values());
}
This implementation:
- Uses TypeScript interfaces for better type checking.
- Clarifies that
shortcuts
is an object with string keys andShortcutItem
values. - Renames the function to
getUniqueShortcutItems
for clarity. - Uses a
Map
to store unique shortcuts, which is more idiomatic and efficient. - Builds and returns the array in one step, avoiding the need for
Object.values
at the end. - Checks if
item.shortcut
exists before using it, preventing potential undefined behavior.
To ensure this change doesn't break existing usage, please run the following command to check current usage of the function:
If there are any usages, make sure to update them accordingly.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
rg --type typescript "shortcutToHelpItems"
Length of output: 77
Script:
#!/bin/bash
# Searching for the usage of `shortcutToHelpItems` in TypeScript files
rg --type ts "shortcutToHelpItems"
Length of output: 571
@@ -105,6 +105,7 @@ export const getStandardizedUrls = ( | |||
urls: | |||
| readonly { readonly field: string; readonly url: string }[] | |||
| { [field: string]: string } | |||
| ModalSample["urls"] |
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.
💡 Codebase verification
Implementation does not handle new ModalSample["urls"] type
The getStandardizedUrls
function signature now accepts ModalSample["urls"]
as a possible type, but the function body lacks the necessary handling for this type. Ensure that the function correctly processes ModalSample["urls"]
to maintain type safety and functionality.
- File: app/packages/state/src/utils.ts
- Function:
getStandardizedUrls
- Function:
🔗 Analysis chain
Function signature updated correctly, verify implementation
The addition of ModalSample["urls"]
as a possible type for the urls
parameter enhances the function's flexibility. This change is consistent with the updated import statement.
Please verify that the function body can handle the new ModalSample["urls"]
type correctly. Run the following script to check the implementation:
If the function body doesn't handle the new type explicitly, consider adding appropriate type checks or assertions to ensure type safety.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify the implementation of getStandardizedUrls function
# Test: Check if the function handles ModalSample["urls"] type
ast-grep --lang typescript --pattern 'function getStandardizedUrls($_) {
$$$
if (!Array.isArray(urls)) {
return urls;
}
$$$
}'
# Test: Check if there are any type assertions or checks for ModalSample["urls"]
rg --type typescript 'ModalSample\["urls"\]' app/packages/state/src/utils.ts
Length of output: 254
Script:
#!/bin/bash
# Description: Verify the implementation of getStandardizedUrls function
# Test: Check if the function handles ModalSample["urls"] type
ast-grep --lang typescript --pattern 'function getStandardizedUrls($_) {
$$$
if (!Array.isArray(urls)) {
return urls;
}
$$$
}'
# Test: Check if there are any type assertions or checks for ModalSample["urls"]
rg 'ModalSample\["urls"\]' app/packages/state/src/utils.ts
Length of output: 227
Script:
#!/bin/bash
# Description: Further verify the implementation of getStandardizedUrls function with ModalSample["urls"]
# Test: Broaden ast-grep pattern to capture any handling of ModalSample["urls"]
ast-grep --lang typescript --pattern 'function getStandardizedUrls($_) {
$$$
if (!Array.isArray(urls)) {
return urls;
}
$$$
}'
# Test: Search for any handling of ModalSample["urls"] within the function
ast-grep --lang typescript --pattern 'getStandardizedUrls($_) {
$$$
if (urls instanceof ModalSample["urls"]) {
$$$
}
$$$
}'
# Test: Find any utility functions or type assertions related to ModalSample["urls"]
rg 'ModalSample\["urls"\]' app/packages/state/src/utils.ts
Length of output: 884
shouldHandleKeyEvents: id === hoveredId, | ||
}); | ||
} | ||
}, [hoveredId, id, looker, ref]); |
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.
🛠️ Refactor suggestion
Optimize Dependency Array in useEffect
The ref
object in the dependency array doesn't trigger updates when its current
value changes because the object reference remains the same. If you intend to react to changes in ref.current
, you should adjust your approach.
Consider using a state or a derived value to trigger updates when ref.current
changes, or, if ref
doesn't change, you can remove it from the dependency array:
useEffect(() => {
// existing code
-}, [hoveredId, id, looker, ref]);
+}, [hoveredId, id, looker]);
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
}, [hoveredId, id, looker, ref]); | |
}, [hoveredId, id, looker]); |
useEffect(() => { | ||
if (ref.current) { | ||
// initial call should wait for load event | ||
const update = () => { | ||
looker.updateOptions({ | ||
shouldHandleKeyEvents: id === hoveredId, | ||
}); | ||
ready.current = true; | ||
|
||
looker.removeEventListener("load", update); | ||
}; | ||
looker.addEventListener("load", update); | ||
} else if (ready.current) { | ||
looker.updateOptions({ | ||
shouldHandleKeyEvents: id === hoveredId, | ||
}); | ||
} | ||
}, [hoveredId, id, looker, ref]); |
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.
Add Cleanup Function in useEffect
to Prevent Memory Leaks
When adding event listeners within a useEffect
, it's important to clean them up to prevent memory leaks. Currently, if the component unmounts before the 'load'
event fires, the event listener may not be removed.
Refactor the useEffect
hook to include a cleanup function:
export default function useKeyEvents(
ref: MutableRefObject<boolean>,
id: string,
looker: Lookers
) {
const hoveredId = useRecoilValue(hoveredSampleId);
const ready = useRef(false);
useEffect(() => {
+ const update = () => {
+ looker.updateOptions({
+ shouldHandleKeyEvents: id === hoveredId,
+ });
+ ready.current = true;
+ looker.removeEventListener("load", update);
+ };
if (ref.current) {
// initial call should wait for load event
- const update = () => {
- looker.updateOptions({
- shouldHandleKeyEvents: id === hoveredId,
- });
- ready.current = true;
- looker.removeEventListener("load", update);
- };
looker.addEventListener("load", update);
} else if (ready.current) {
looker.updateOptions({
shouldHandleKeyEvents: id === hoveredId,
});
}
+ return () => {
+ looker.removeEventListener("load", update);
+ };
}, [hoveredId, id, looker, ref]);
}
This ensures the event listener is removed when the component unmounts, even if the 'load'
event hasn't fired yet.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
useEffect(() => { | |
if (ref.current) { | |
// initial call should wait for load event | |
const update = () => { | |
looker.updateOptions({ | |
shouldHandleKeyEvents: id === hoveredId, | |
}); | |
ready.current = true; | |
looker.removeEventListener("load", update); | |
}; | |
looker.addEventListener("load", update); | |
} else if (ready.current) { | |
looker.updateOptions({ | |
shouldHandleKeyEvents: id === hoveredId, | |
}); | |
} | |
}, [hoveredId, id, looker, ref]); | |
useEffect(() => { | |
const update = () => { | |
looker.updateOptions({ | |
shouldHandleKeyEvents: id === hoveredId, | |
}); | |
ready.current = true; | |
looker.removeEventListener("load", update); | |
}; | |
if (ref.current) { | |
// initial call should wait for load event | |
looker.addEventListener("load", update); | |
} else if (ready.current) { | |
looker.updateOptions({ | |
shouldHandleKeyEvents: id === hoveredId, | |
}); | |
} | |
return () => { | |
looker.removeEventListener("load", update); | |
}; | |
}, [hoveredId, id, looker, ref]); |
const frameRate = useMemo(() => { | ||
return sample.frameRate; | ||
}, [sample]); |
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.
🛠️ Refactor suggestion
Consider removing unnecessary useMemo
for frameRate
Using useMemo
to memoize a simple scalar value like sample.frameRate
is unnecessary and adds complexity without performance benefits. You can directly assign the value to frameRate
.
Apply this diff to simplify the code:
-const frameRate = useMemo(() => {
- return sample.frameRate;
-}, [sample]);
+const frameRate = sample.frameRate;
Ensure to update the dependencies in the useEffect
hook accordingly.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
const frameRate = useMemo(() => { | |
return sample.frameRate; | |
}, [sample]); | |
const frameRate = sample.frameRate; |
const looker = React.useMemo(() => { | ||
/** start refreshers */ | ||
reset; | ||
selectedMediaField; | ||
/** end refreshers */ | ||
|
||
return createLooker.current(sample); | ||
}, [createLooker, reset, sample, selectedMediaField]) as L; |
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.
🛠️ Refactor suggestion
Remove unnecessary expressions inside useMemo
The expressions reset;
and selectedMediaField;
within the useMemo
function body do not have any operational effect. Including them may cause confusion for other developers reading the code. Since these variables are already in the dependency array and if they do not directly influence the computation inside useMemo
, consider removing these expressions to clean up the code.
Apply this diff to remove the unnecessary expressions:
const looker = React.useMemo(() => {
- /** start refreshers */
- reset;
- selectedMediaField;
- /** end refreshers */
return createLooker.current(sample);
}, [createLooker, reset, sample, selectedMediaField]) as L;
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
const looker = React.useMemo(() => { | |
/** start refreshers */ | |
reset; | |
selectedMediaField; | |
/** end refreshers */ | |
return createLooker.current(sample); | |
}, [createLooker, reset, sample, selectedMediaField]) as L; | |
const looker = React.useMemo(() => { | |
return createLooker.current(sample); | |
}, [createLooker, reset, sample, selectedMediaField]) as L; |
useEffect(() => { | ||
/** start refreshers */ | ||
colorScheme; | ||
/** end refreshers */ | ||
|
||
!initialRef.current && looker.updateSample(sample); | ||
}, [colorScheme, looker, sample]); | ||
|
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.
🛠️ Refactor suggestion
Eliminate redundant expression in useEffect
The standalone expression colorScheme;
within this useEffect
doesn't perform any action and might be misleading. Since colorScheme
is already included in the dependency array, and if it's not used inside the effect, you can safely remove this expression to improve code clarity.
Apply this diff to improve the code:
useEffect(() => {
- /** start refreshers */
- colorScheme;
- /** end refreshers */
!initialRef.current && looker.updateSample(sample);
}, [colorScheme, looker, sample]);
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
useEffect(() => { | |
/** start refreshers */ | |
colorScheme; | |
/** end refreshers */ | |
!initialRef.current && looker.updateSample(sample); | |
}, [colorScheme, looker, sample]); | |
useEffect(() => { | |
!initialRef.current && looker.updateSample(sample); | |
}, [colorScheme, looker, sample]); |
const [id] = useState(() => uuid()); | ||
const initialRef = useRef<boolean>(true); | ||
const ref = useRef<HTMLDivElement>(null); | ||
const [reset, setReset] = useState(false); | ||
const lookerOptions = fos.useLookerOptions(true); | ||
const createLooker = fos.useCreateLooker( | ||
true, | ||
false, | ||
lookerOptions, | ||
undefined, | ||
true | ||
); | ||
const selectedMediaField = useRecoilValue(fos.selectedMediaField(true)); |
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.
🛠️ Refactor suggestion
Memoize createLooker
to prevent unnecessary re-creations
The createLooker
function might be redefined on every render if fos.useCreateLooker
does not memoize its result. This can lead to unnecessary re-creation of the looker
instance. Consider memoizing createLooker
to ensure that it remains stable across renders unless its dependencies change.
You can memoize createLooker
like this:
const createLooker = React.useMemo(() => fos.useCreateLooker(
true,
false,
lookerOptions,
undefined,
true
- ), []);
+ ), [lookerOptions]);
Ensure that fos.useCreateLooker
is suitable for memoization in this manner.
Committable suggestion was skipped due to low confidence.
schema.getFieldsWithEmbeddedDocType( | ||
SCHEMA, | ||
"fiftyone.core.labels.TopLabel" | ||
) | ||
).toEqual([SCHEMA.top]); | ||
}); | ||
|
||
it("should get all fields with embeddedDocType in nested fields", () => { | ||
expect( | ||
schema.getFieldsWithEmbeddedDocType( | ||
SCHEMA, | ||
"fiftyone.core.labels.EmbeddedLabel" | ||
) | ||
).toEqual([ | ||
SCHEMA.embedded.fields!.field, | ||
SCHEMA.embeddedWithDbFields.fields!.sample_id, | ||
]); | ||
}); | ||
|
||
it("should return empty array if embeddedDocType does not exist", () => { | ||
expect( | ||
schema.getFieldsWithEmbeddedDocType(SCHEMA, "nonexistentDocType") | ||
).toEqual([]); | ||
}); | ||
|
||
it("should return empty array for empty schema", () => { | ||
expect(schema.getFieldsWithEmbeddedDocType({}, "anyDocType")).toEqual([]); | ||
}); | ||
}); | ||
|
||
describe("doesSchemaContainEmbeddedDocType", () => { | ||
it("should return true if embeddedDocType exists at top level", () => { | ||
expect( | ||
schema.doesSchemaContainEmbeddedDocType( | ||
SCHEMA, | ||
"fiftyone.core.labels.TopLabel" | ||
) | ||
).toBe(true); | ||
}); | ||
|
||
it("should return true if embeddedDocType exists in nested fields", () => { | ||
expect( | ||
schema.doesSchemaContainEmbeddedDocType( | ||
SCHEMA, | ||
"fiftyone.core.labels.EmbeddedLabel" | ||
) |
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.
🛠️ Refactor suggestion
Consider Using Constants for Embedded Document Type Strings
The embedded document type strings, such as "fiftyone.core.labels.TopLabel"
and "fiftyone.core.labels.EmbeddedLabel"
, are repeated across multiple test cases. To enhance maintainability and reduce the potential for typos, consider defining these strings as constants or enumerations.
Example:
const TOP_LABEL = "fiftyone.core.labels.TopLabel";
const EMBEDDED_LABEL = "fiftyone.core.labels.EmbeddedLabel";
Then use them in your tests:
expect(
schema.getFieldsWithEmbeddedDocType(SCHEMA, TOP_LABEL)
).toEqual([SCHEMA.top]);
getVideo() { | ||
return this.lookerElement.children[0].element as HTMLVideoElement; | ||
} |
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.
Add null checks to prevent potential runtime errors
The method getVideo()
assumes that this.lookerElement.children[0]
and this.lookerElement.children[0].element
are always defined. If children
is empty or element
is undefined, this will cause a runtime error. Consider adding null checks to ensure these properties exist before accessing them.
Apply this diff to add null checks:
-getVideo() {
- return this.lookerElement.children[0].element as HTMLVideoElement;
+getVideo() {
+ const child = this.lookerElement.children[0];
+ if (child && child.element) {
+ return child.element as HTMLVideoElement;
+ }
+ return null;
+}
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
getVideo() { | |
return this.lookerElement.children[0].element as HTMLVideoElement; | |
} | |
getVideo() { | |
const child = this.lookerElement.children[0]; | |
if (child && child.element) { | |
return child.element as HTMLVideoElement; | |
} | |
return null; | |
} |
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.
lgtm!
Adds #4876 and #4878 to
release/v1.0.1
Summary by CodeRabbit
New Features
VideoLookerReact
component for enhanced video playback functionality.useLooker
anduseKeyEvents
hooks for improved event handling and lifecycle management.VideoLooker
class.Improvements
ModalLooker
andModalLookerNoTimeline
components for better clarity and maintainability.Bug Fixes