Skip to content
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

feat: timer preview #1208

Merged
merged 2 commits into from
Sep 27, 2024
Merged

feat: timer preview #1208

merged 2 commits into from
Sep 27, 2024

Conversation

cpvalente
Copy link
Owner

@cpvalente cpvalente commented Sep 3, 2024

WIP

The idea is to help users manage the timer view and make things friendlier
https://www.figma.com/design/TOjSQ4e8q4dhNDNN5DElD3/ontime?node-id=1722-6&t=9OAa5afIUFi2Ule1-1

This also helps resolve #1024

Screenshot 2024-09-20 at 22 34 11

  • expose button to show auxiliary as secondary
  • expose button to show external as secondary (previously disabled)
  • create preview of timer
  • show timer type with tooltips in preview
  • show timer phase (warning / danger) in preview

Questions:

The button for external visibility is duplicated, I experimented without it but it felt strange to have two different inputs for External Message and Timer Message. I am not sure what the best way is here

I opted for not showing the real message and time to be conservative of performance. While this is a nice feature, I didnt feel it was worth the performance investment. However we could do better at showing the current formatting from settings (eg: HH:MM), any ideas for this?

Copy link
Contributor

coderabbitai bot commented Sep 3, 2024

Walkthrough

The changes involve significant updates across multiple files, focusing on enhancing timer management and message handling functionalities. Modifications include the introduction of new hooks for message previews, restructuring components for better organization, and refactoring the message service from a class-based to a functional approach. Additionally, new validation mechanisms for timer messages have been implemented, improving the overall robustness of the application.

Changes

Files Change Summary
apps/client/src/common/hooks/useSocket.ts Enhanced message handling with new useTimerMessageInput, useExternalMessageInput, and useMessagePreview hooks; updated methods for external messages and timer secondary state.
apps/client/src/common/stores/runtime.ts Simplified runtimeStorePlaceholder by changing external from an object to a string and adding secondarySource.
apps/client/src/features/app-settings/panel/general-panel/ViewSettingsForm.tsx Minor update to placeholder text in input field for clarity.
apps/client/src/features/control/message/InputRow.tsx Removed readonly property from InputRowProps, allowing input fields to always be editable.
apps/client/src/features/control/message/MessageControl.module.scss Introduced new CSS classes for improved layout and presentation in the MessageControl component.
apps/client/src/features/control/message/MessageControl.tsx Streamlined MessageControl logic, updated input handling, and removed button controls for blinking and blackout.
apps/client/src/features/control/message/TimerPreview.tsx Introduced TimerPreview component for visual representation of timer statuses and states.
apps/client/src/features/control/message/TimerViewControl.tsx Added TimerControlsPreview component for managing timer settings and interactions.
apps/server/src/api-integration/integration.controller.ts Changed messageService import to a namespace import for clarity; updated action handler to manage legacy message conversion.
apps/server/src/api-integration/integration.legacy.ts Introduced functionality for handling legacy message state data, including type guard and conversion function.
apps/server/src/app.ts Modified messageService import to namespace import; adjusted init method invocation.
apps/server/src/services/message-service/MessageService.ts Refactored MessageService to a module-based approach, removing the singleton pattern.
apps/server/src/services/message-service/messageUtils.ts Simplified validateMessage function; enhanced validateTimerMessage to support new secondarySource property with additional validation functions.
apps/server/src/services/message-service/__tests__/MessageService.test.ts Updated tests to reflect changes in external property structure and added secondarySource to expected outputs.
apps/server/src/services/message-service/__tests__/messageUtils.test.ts Removed old tests for validateMessage; added new test for simple string input.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Socket
    participant Server
    participant MessageService

    Client->>Socket: sendMessage(message)
    Socket->>Server: forwardMessage(message)
    Server->>MessageService: processMessage(message)
    MessageService-->>Server: updateState(newState)
    Server-->>Socket: sendResponse(response)
    Socket-->>Client: receiveResponse(response)
Loading

Assessment against linked issues

Objective Addressed Explanation
Ensure timer functionalities are clear in the editor (1024) Changes related to timer management were made, but it's unclear if they resolve the specific issue of timer behavior.

Possibly related PRs

  • Timeline duration #1178: The addition of the useTimelineOverview hook in useSocket.ts enhances the messaging system by providing access to timeline-related data, complementing the new message handling features.

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?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

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)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between aa4ee54 and 69e76ac.

Files ignored due to path filters (2)
  • apps/server/tsconfig.json is excluded by none and included by none
  • packages/types/src/definitions/runtime/MessageControl.type.ts is excluded by none and included by none
Files selected for processing (7)
  • apps/client/src/common/hooks/useSocket.ts (3 hunks)
  • apps/client/src/features/control/message/MessageControl.module.scss (1 hunks)
  • apps/client/src/features/control/message/MessageControl.tsx (1 hunks)
  • apps/server/src/api-integration/integration.controller.ts (2 hunks)
  • apps/server/src/app.ts (2 hunks)
  • apps/server/src/services/message-service/MessageService.ts (1 hunks)
  • apps/server/src/services/message-service/messageUtils.ts (1 hunks)
Additional context used
Biome
apps/server/src/services/message-service/MessageService.ts

[error] 48-48: Unexpected label.

Only loops should be labeled.
The use of labels for other statements is suspicious and unfamiliar.

(lint/suspicious/noConfusingLabels)


[error] 48-48: Unused label.

The label is not used by any break statement and continue statement.
Safe fix: Remove the unused label.

(lint/correctness/noUnusedLabels)

Additional comments not posted (18)
apps/client/src/features/control/message/MessageControl.module.scss (3)

30-34: LGTM!

The .timerPreview class uses a grid layout with specified column ratios, allowing for a structured arrangement of child elements. The changes are consistent with the AI-generated summary.


36-41: LGTM!

The .preview class centers its content both vertically and horizontally, improving visual focus. The background color set to $ui-black enhances visual contrast. The changes are consistent with the AI-generated summary.


43-47: LGTM!

The .options class uses a flexbox layout to stack its child elements vertically, promoting better spacing and organization. The defined gap between the child elements improves the spacing. The changes are consistent with the AI-generated summary.

apps/server/src/services/message-service/MessageService.ts (3)

6-12: LGTM!

The code changes are approved.


14-17: LGTM!

The code changes are approved.


19-22: LGTM!

The code changes are approved.

apps/server/src/services/message-service/messageUtils.ts (3)

33-33: LGTM!

The code segment correctly handles the secondary property and uses the coerceSecondary function for validation and coercion.

Verify the implementation of the coerceSecondary function in the file.


41-43: LGTM!

The assertSecondary function correctly asserts the permitted values for the secondary property.


48-53: LGTM!

The coerceSecondary function correctly ensures that the secondary value is one of the permitted values and throws an error for invalid values, providing a robust error handling mechanism.

apps/client/src/features/control/message/MessageControl.tsx (3)

16-34: LGTM!

The TimerPreview function is a great addition that improves the separation of concerns and makes the logic for handling timer states more explicit.


36-90: LGTM!

The TimerControlsPreview function is a great addition that improves the separation of concerns and makes the logic for handling user interactions more explicit.


Line range hint 92-116: LGTM!

The MessageControl function has been refactored to include two new components: TimerPreview and TimerControlsPreview, which improves the separation of concerns and makes the code more readable and maintainable.

apps/client/src/common/hooks/useSocket.ts (3)

1-1: LGTM!

The import statement change is approved. The addition of TimerMessage is consistent with the AI-generated summary, which suggests that the file now handles new message types associated with timers.


35-35: LGTM!

The state selection logic change is approved. Replacing onAir with phase indicates a shift in focus towards the timer's current phase rather than its on-air status. This change is consistent with the AI-generated summary, which suggests a broader requirement for timer state management in the application.


46-46: LGTM!

The addition of timerSecondary method is approved. The method enhances the communication capabilities of the application by allowing for more granular control over timer states. It is consistent with the AI-generated summary, which indicates that the application now supports additional timer-related functionalities.

apps/server/src/app.ts (2)

41-41: LGTM!

The code change is approved.


213-213: Verify the impact of the change on the init method.

The updated code passes eventStore.set directly to the init method, which implies that the context will be determined by how init is called. This change may affect the behavior of the init method if it relies on the context of this, depending on its implementation.

Run the following script to verify the implementation of the init method:

apps/server/src/api-integration/integration.controller.ts (1)

6-6: LGTM!

The refactor from a default import to a namespace import for messageService is approved.

apps/server/src/services/message-service/MessageService.ts Outdated Show resolved Hide resolved
apps/server/src/api-integration/integration.controller.ts Outdated Show resolved Hide resolved
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 69e76ac and 7bf62f2.

Files ignored due to path filters (2)
  • apps/server/tsconfig.json is excluded by none and included by none
  • packages/types/src/definitions/runtime/MessageControl.type.ts is excluded by none and included by none
Files selected for processing (18)
  • apps/client/src/common/hooks/useSocket.ts (3 hunks)
  • apps/client/src/features/app-settings/panel/general-panel/ViewSettingsForm.tsx (1 hunks)
  • apps/client/src/features/control/message/InputRow.tsx (2 hunks)
  • apps/client/src/features/control/message/MessageControl.module.scss (1 hunks)
  • apps/client/src/features/control/message/MessageControl.tsx (1 hunks)
  • apps/client/src/features/control/message/MessageControlExport.jsx (1 hunks)
  • apps/client/src/features/control/message/TimerPreview.tsx (1 hunks)
  • apps/client/src/features/control/message/TimerViewControl.tsx (1 hunks)
  • apps/client/src/features/control/playback/aux-timer/AuxTimer.tsx (1 hunks)
  • apps/client/src/features/editors/Editor.module.scss (2 hunks)
  • apps/client/src/features/editors/EditorMixin.scss (2 hunks)
  • apps/client/src/features/rundown/event-block/EventBlockInner.tsx (3 hunks)
  • apps/client/src/features/viewers/ViewWrapper.tsx (2 hunks)
  • apps/client/src/features/viewers/timer/Timer.tsx (6 hunks)
  • apps/server/src/api-integration/integration.controller.ts (2 hunks)
  • apps/server/src/app.ts (2 hunks)
  • apps/server/src/services/message-service/MessageService.ts (1 hunks)
  • apps/server/src/services/message-service/messageUtils.ts (1 hunks)
Files skipped from review due to trivial changes (3)
  • apps/client/src/features/app-settings/panel/general-panel/ViewSettingsForm.tsx
  • apps/client/src/features/control/playback/aux-timer/AuxTimer.tsx
  • apps/client/src/features/rundown/event-block/EventBlockInner.tsx
Files skipped from review as they are similar to previous changes (4)
  • apps/client/src/features/control/message/MessageControl.module.scss
  • apps/server/src/api-integration/integration.controller.ts
  • apps/server/src/app.ts
  • apps/server/src/services/message-service/messageUtils.ts
Additional context used
Biome
apps/server/src/services/message-service/MessageService.ts

[error] 48-48: Unexpected label.

Only loops should be labeled.
The use of labels for other statements is suspicious and unfamiliar.

(lint/suspicious/noConfusingLabels)


[error] 48-48: Unused label.

The label is not used by any break statement and continue statement.
Safe fix: Remove the unused label.

(lint/correctness/noUnusedLabels)

Additional comments not posted (15)
apps/client/src/features/editors/EditorMixin.scss (2)

5-7: Good use of CSS custom properties.

The introduction of --editor--panel__br at the root level promotes consistency and maintainability in styling. Well done!


30-30: Enhanced flexibility with CSS custom properties.

Using var(--editor--panel__br) for the border-radius in the panel mixin is a great way to maintain consistency and ease future modifications.

apps/client/src/features/control/message/MessageControlExport.jsx (1)

6-18: Good use of utility function for class management.

The introduction and usage of the cx function from styleUtils to dynamically manage class names enhances the flexibility and maintainability of the component's styling. This is a good practice.

apps/client/src/features/control/message/MessageControl.tsx (1)

4-28: Streamlined component structure and state management.

The restructuring of the MessageControl function to directly access timer and external properties simplifies state management. The introduction of the TimerControlsPreview component enhances focus on essential functionalities. These changes improve readability and maintainability.

apps/client/src/features/editors/Editor.module.scss (2)

43-43: Approved: Use of CSS variables for styling consistency.

The update to use var(--editor--panel__br) for the border-radius property in .playback and .messages classes enhances styling consistency across the application.


66-71: Approved: Addition of .contentColumnLayout for enhanced layout management.

The new .contentColumnLayout class with flex properties and defined gap improves the structural organization and visual appeal of the content areas. Using $ui-white for text color ensures consistency with the theme.

apps/server/src/services/message-service/MessageService.ts (2)

28-30: Approved: Use of throttled function in init.

The implementation of a throttled publish function in the init method is a good practice to manage performance and reduce unnecessary load.


35-39: Approved: Simplified state retrieval in getState.

The direct return of the timer and external message states in the getState function simplifies the code and enhances readability.

apps/client/src/features/control/message/TimerViewControl.tsx (1)

9-62: Approved: Well-implemented timer controls with best practices.

The TimerControlsPreview function effectively uses React hooks and functional components to manage and display timer settings. The implementation is clean, and the use of conditional rendering and event handling is well-executed.

apps/client/src/features/control/message/InputRow.tsx (1)

Line range hint 23-63: Simplified Component Logic by Removing readonly Property

The removal of the readonly property simplifies the component's logic by always rendering the TooltipActionBtn, which enhances user interaction by allowing visibility toggling at all times. This change streamlines the component and removes unnecessary conditional checks.

However, it's important to verify that this change does not affect other functionalities or components that might rely on the readonly state.

Run the following script to verify the impact of this change on other components:

Verification successful

Simplified Component Logic by Removing readonly Property

The removal of the readonly property from the InputRow component does not negatively impact other components, such as MessageControl, which uses the visible prop to manage visibility. This change aligns with the intended functionality and simplifies the component logic without affecting other parts of the codebase.

  • The MessageControl component uses the InputRow component with the visible prop, ensuring consistent behavior.
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify if other components are affected by the removal of the `readonly` property.

# Test: Search for the usage of `InputRow` component. Expect: No other components should rely on the `readonly` property.
rg --type typescript -A 5 $'InputRow'

Length of output: 71


Script:

#!/bin/bash
# Description: Verify if other components are affected by the removal of the `readonly` property.

# Test: Search for the usage of `InputRow` component. Expect: No other components should rely on the `readonly` property.
rg --type ts -A 10 'InputRow'

Length of output: 4596

apps/client/src/features/control/message/TimerPreview.tsx (1)

15-92: Robust Implementation of TimerPreview Component

The TimerPreview component is well-implemented, using hooks effectively to fetch and manage state, and employing conditional rendering to adapt the UI based on the timer's visibility, phase, and secondary messages. The dynamic styling based on the timer phase is a thoughtful touch that enhances the user experience.

Ensure that all data dependencies are correctly managed and that the component gracefully handles any potential data fetching issues or delays.

Run the following script to verify the data dependencies:

Verification successful

Verification Successful: Data Dependencies in TimerPreview Component

The TimerPreview component's data dependencies are managed correctly. The useViewSettings hook includes error handling and retry logic, while the useMessagePreview hook is part of a state management system. This ensures that the component can handle data fetching states and potential errors gracefully. No further action is needed.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the data dependencies for the `TimerPreview` component.

# Test: Search for the usage of hooks in the component. Expect: All hooks should have proper error handling and fallbacks.
rg --type typescript -A 5 $'useMessagePreview|useViewSettings'

Length of output: 98


Script:

#!/bin/bash
# Description: Verify the data dependencies for the `TimerPreview` component.

# Test: Search for the usage of hooks in the component. Expect: All hooks should have proper error handling and fallbacks.
rg --type ts -A 5 'useMessagePreview|useViewSettings'

Length of output: 7209

apps/client/src/features/viewers/ViewWrapper.tsx (1)

Line range hint 71-99: Enhanced Data Handling with Addition of auxtimer1

The addition of the auxtimer1 property to the destructured object from the useStore(runtimeStore) hook and its subsequent passing as a prop to the wrapped component enhances the component's functionality by allowing it to handle an additional timer state. This change reflects an improvement in the component's data handling capabilities.

Ensure that the auxtimer1 property is correctly integrated and used by the wrapped component without causing any unintended side effects.

Run the following script to verify the integration and usage of the auxtimer1 property:

Verification successful

Successful Integration of auxtimer1 Property

The auxtimer1 property is well-integrated across the codebase, with its definition, initialization, and usage evident in multiple files. It is part of the application's state management and is used in real-time updates, confirming its proper integration and functionality.

  • Definition: auxtimer1 is defined as a SimpleTimerState in RuntimeStore.type.ts.
  • Initialization: Initialized with default values in app.ts and runtime.ts.
  • Usage: Passed as a prop in ViewWrapper.tsx and referenced in socket-related files (socket.ts, useSocket.ts).
  • Service Interaction: Used in AuxTimerService.ts, indicating its role in the service layer.
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the integration and usage of the `auxtimer1` property.

# Test: Search for the usage of `auxtimer1` in the wrapped components. Expect: Proper handling and usage of the property.
rg --type typescript -A 5 $'auxtimer1'

Length of output: 72


Script:

#!/bin/bash
# Description: Verify the integration and usage of the `auxtimer1` property.

# Test: Search for the usage of `auxtimer1` in the wrapped components. Expect: Proper handling and usage of the property.
rg --type ts -A 5 $'auxtimer1'

Length of output: 4065

apps/client/src/common/hooks/useSocket.ts (1)

57-61: Enhancements to message handling approved.

The new methods externalText, externalVisible, and timerSecondary in the setMessage object are correctly implemented and enhance the application's message handling capabilities, particularly in relation to timer management and external message functionalities.

apps/client/src/features/viewers/timer/Timer.tsx (2)

Line range hint 64-211: Enhancements to the Timer function approved.

The use of the auxTimer property to conditionally render secondary content and the updated logic for external content visibility are correctly implemented, enhancing the component's functionality and aligning with the PR objectives.


51-51: Addition of auxTimer to TimerProps approved.

The new property auxTimer enhances the component's functionality by allowing conditional rendering based on the timer's state. Please ensure that the SimpleTimerState type is fully compatible with the intended use cases.

Run the following script to verify the type compatibility:

Verification successful

Compatibility of SimpleTimerState with Timer Component Confirmed

The SimpleTimerState type is well-defined and used consistently across the codebase, including in the SimpleTimer class and related tests. This confirms its compatibility with the Timer component's requirements. The addition of auxTimer to the TimerProps interface is approved and aligns with the intended functionality enhancements.

  • Definition found in packages/types/src/definitions/runtime/AuxTimer.type.ts
  • Utilized in apps/server/src/classes/simple-timer/SimpleTimer.ts and related tests
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the compatibility of `SimpleTimerState` type with its usage in the `Timer` component.

# Test: Search for the type definition and its usage. Expect: Compatibility with the `Timer` component's requirements.
rg --type typescript -A 5 $'SimpleTimerState'

Length of output: 79


Script:

#!/bin/bash
# Description: Search for the definition and usage of `SimpleTimerState` in TypeScript files.

# Search for the definition of `SimpleTimerState` in `.ts` and `.tsx` files.
rg 'SimpleTimerState' --glob '**/*.ts' --glob '**/*.tsx' -A 5

Length of output: 13347

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 7bf62f2 and 55ee7dd.

Files ignored due to path filters (2)
  • apps/server/tsconfig.json is excluded by none and included by none
  • packages/types/src/definitions/runtime/MessageControl.type.ts is excluded by none and included by none
Files selected for processing (18)
  • apps/client/src/common/hooks/useSocket.ts (3 hunks)
  • apps/client/src/features/app-settings/panel/general-panel/ViewSettingsForm.tsx (1 hunks)
  • apps/client/src/features/control/message/InputRow.tsx (2 hunks)
  • apps/client/src/features/control/message/MessageControl.module.scss (1 hunks)
  • apps/client/src/features/control/message/MessageControl.tsx (1 hunks)
  • apps/client/src/features/control/message/MessageControlExport.jsx (1 hunks)
  • apps/client/src/features/control/message/TimerPreview.tsx (1 hunks)
  • apps/client/src/features/control/message/TimerViewControl.tsx (1 hunks)
  • apps/client/src/features/control/playback/aux-timer/AuxTimer.tsx (1 hunks)
  • apps/client/src/features/editors/Editor.module.scss (2 hunks)
  • apps/client/src/features/editors/EditorMixin.scss (2 hunks)
  • apps/client/src/features/rundown/event-block/EventBlockInner.tsx (3 hunks)
  • apps/client/src/features/viewers/ViewWrapper.tsx (2 hunks)
  • apps/client/src/features/viewers/timer/Timer.tsx (6 hunks)
  • apps/server/src/api-integration/integration.controller.ts (2 hunks)
  • apps/server/src/app.ts (2 hunks)
  • apps/server/src/services/message-service/MessageService.ts (1 hunks)
  • apps/server/src/services/message-service/messageUtils.ts (1 hunks)
Files skipped from review due to trivial changes (4)
  • apps/client/src/features/app-settings/panel/general-panel/ViewSettingsForm.tsx
  • apps/client/src/features/control/playback/aux-timer/AuxTimer.tsx
  • apps/client/src/features/editors/EditorMixin.scss
  • apps/client/src/features/rundown/event-block/EventBlockInner.tsx
Files skipped from review as they are similar to previous changes (9)
  • apps/client/src/common/hooks/useSocket.ts
  • apps/client/src/features/control/message/InputRow.tsx
  • apps/client/src/features/control/message/MessageControl.module.scss
  • apps/client/src/features/control/message/MessageControlExport.jsx
  • apps/client/src/features/control/message/TimerPreview.tsx
  • apps/client/src/features/control/message/TimerViewControl.tsx
  • apps/server/src/api-integration/integration.controller.ts
  • apps/server/src/app.ts
  • apps/server/src/services/message-service/messageUtils.ts
Additional context used
Biome
apps/server/src/services/message-service/MessageService.ts

[error] 48-48: Unexpected label.

Only loops should be labeled.
The use of labels for other statements is suspicious and unfamiliar.

(lint/suspicious/noConfusingLabels)


[error] 48-48: Unused label.

The label is not used by any break statement and continue statement.
Safe fix: Remove the unused label.

(lint/correctness/noUnusedLabels)

Additional comments not posted (7)
apps/client/src/features/control/message/MessageControl.tsx (2)

11-11: Acknowledgment of TimerControlsPreview.

The function TimerControlsPreview is mentioned in the alterations but no specific changes are highlighted in the provided code. If internal changes were made, ensure they align with the overall objectives of the PR.


4-28: Refactor enhances clarity and maintainability.

The restructuring of the MessageControl function simplifies the handling of timer and external messages by using destructured properties directly. This change enhances the component's readability and maintainability by reducing complexity.

Run the following script to verify the integration with the rest of the application:

Verification successful

Integration of MessageControl is verified.

The MessageControl component is properly integrated into the application, as evidenced by its usage in multiple files and its dynamic import using React.lazy. This confirms that the refactoring maintains the component's functionality within the application.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the integration of `MessageControl` with the rest of the application.

# Test: Search for the usage of `MessageControl` in other components. Expect: Proper integration without issues.
rg --type tsx -A 5 $'MessageControl'

Length of output: 63


Script:

#!/bin/bash
# Find all .tsx files and search for the usage of `MessageControl` within them.
fd --extension tsx --exec rg 'MessageControl' {}

Length of output: 697

apps/client/src/features/editors/Editor.module.scss (2)

43-43: Enhanced styling consistency.

Updating the border-radius property to use a variable (var(--editor--panel__br)) enhances styling consistency and maintainability across the application.


66-71: New class enhances layout capabilities.

The introduction of the .contentColumnLayout class, applying a flexbox layout with column direction and defined spacing, enhances the layout capabilities and promotes a more structured and visually appealing design.

Run the following script to verify the integration of .contentColumnLayout with the rest of the application:

Verification successful

Integration of .contentColumnLayout verified.

The .contentColumnLayout class is used in the MessageControlExport.jsx file, confirming its integration into the application. No issues were found with its usage.

  • File: apps/client/src/features/control/message/MessageControlExport.jsx
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the integration of `.contentColumnLayout` with the rest of the application.

# Test: Search for the usage of `.contentColumnLayout` in other components. Expect: Proper integration without issues.
rg --type scss -A 5 $'.contentColumnLayout'

Length of output: 71


Script:

#!/bin/bash
# Description: Verify the integration of `.contentColumnLayout` with the rest of the application.

# Test: Search for the usage of `.contentColumnLayout` in the codebase.
rg '.contentColumnLayout'

Length of output: 232

apps/server/src/services/message-service/MessageService.ts (2)

6-21: Initialization of default objects and state variables enhances consistency.

The introduction of default objects for timer and external messages and their use in initializing state variables ensures a consistent starting state for the service. This change enhances the robustness and maintainability of the service.


28-30: Efficient management of updates with throttled publish function.

The setup of a throttled publish function in the init method ensures efficient management of updates, preventing potential performance issues due to rapid state changes.

apps/client/src/features/viewers/timer/Timer.tsx (1)

51-51: Approve the addition of auxTimer and verify its integration.

The addition of auxTimer to the TimerProps interface and its usage in the component are approved. The conditional rendering logic based on auxTimer appears to be correctly implemented. However, ensure that auxTimer is properly integrated and does not introduce any side effects.

Run the following script to verify the integration of auxTimer:

Also applies to: 64-64, 137-142

Verification successful

Integration of auxTimer is verified and correct.

The auxTimer is well-integrated into the Timer component and other parts of the codebase. Its usage is consistent with the intended functionality, and it is covered by tests, indicating no side effects. The integration is successfully verified.

  • Timer.tsx: Declaration and usage in props and rendering logic.
  • integration.controller.ts: Usage in service calls.
  • 208-auxtimer.spec.ts: End-to-end tests covering auxTimer functionality.
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the integration of `auxTimer` in the Timer component.

# Test: Search for the usage of `auxTimer`. Expect: Proper integration without side effects.
rg --type typescript -A 5 $'auxTimer'

Length of output: 71


Script:

#!/bin/bash
# Description: Verify the integration of `auxTimer` in the Timer component.

# Test: Search for the usage of `auxTimer`. Expect: Proper integration without side effects.
rg --type ts -A 5 $'auxTimer'

Length of output: 7247

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Outside diff range and nitpick comments (1)
apps/client/src/features/control/message/TimerPreview.tsx (1)

69-69: Use strict equality operator for consistency

It's best practice to use the strict equality operator === in JavaScript/TypeScript to avoid unexpected type coercion. This ensures that both the value and type are compared.

Apply this diff to update the equality check:

- const showColourOverride = main == 'Timer';
+ const showColourOverride = main === 'Timer';
Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 55ee7dd and 5bc8e9e.

Files ignored due to path filters (1)
  • packages/types/src/definitions/runtime/MessageControl.type.ts is excluded by none and included by none
Files selected for processing (18)
  • apps/client/src/common/hooks/useSocket.ts (3 hunks)
  • apps/client/src/features/app-settings/panel/general-panel/ViewSettingsForm.tsx (1 hunks)
  • apps/client/src/features/control/message/InputRow.tsx (3 hunks)
  • apps/client/src/features/control/message/MessageControl.module.scss (1 hunks)
  • apps/client/src/features/control/message/MessageControl.tsx (1 hunks)
  • apps/client/src/features/control/message/MessageControlExport.jsx (1 hunks)
  • apps/client/src/features/control/message/TimerPreview.tsx (1 hunks)
  • apps/client/src/features/control/message/TimerViewControl.tsx (1 hunks)
  • apps/client/src/features/control/playback/aux-timer/AuxTimer.tsx (1 hunks)
  • apps/client/src/features/editors/Editor.module.scss (2 hunks)
  • apps/client/src/features/editors/EditorMixin.scss (2 hunks)
  • apps/client/src/features/rundown/event-block/EventBlockInner.tsx (2 hunks)
  • apps/client/src/features/viewers/ViewWrapper.tsx (2 hunks)
  • apps/client/src/features/viewers/timer/Timer.tsx (6 hunks)
  • apps/server/src/api-integration/integration.controller.ts (2 hunks)
  • apps/server/src/app.ts (2 hunks)
  • apps/server/src/services/message-service/MessageService.ts (1 hunks)
  • apps/server/src/services/message-service/messageUtils.ts (1 hunks)
Files skipped from review due to trivial changes (3)
  • apps/client/src/features/app-settings/panel/general-panel/ViewSettingsForm.tsx
  • apps/client/src/features/control/playback/aux-timer/AuxTimer.tsx
  • apps/server/src/api-integration/integration.controller.ts
Additional context used
Biome
apps/server/src/services/message-service/MessageService.ts

[error] 48-48: Unexpected label.

Only loops should be labeled.
The use of labels for other statements is suspicious and unfamiliar.

(lint/suspicious/noConfusingLabels)


[error] 48-48: Unused label.

The label is not used by any break statement and continue statement.
Safe fix: Remove the unused label.

(lint/correctness/noUnusedLabels)

Additional comments not posted (28)
apps/client/src/features/editors/EditorMixin.scss (3)

4-7: Introduction of CSS variable for border-radius enhances maintainability

Using --editor--panel__br as a CSS variable for the border-radius centralizes the styling and makes it easier to manage or update the border radius across the application.


9-15: Duplicate Comment: Consider reintroducing mixin usage for positioning

A past review comment addressed the changes in these lines. Please refer to the previous feedback to avoid redundancy.


30-30: Consistent use of CSS variable for border-radius

Updating the border-radius to use the new CSS variable --editor--panel__br ensures consistency and makes future adjustments more manageable.

apps/client/src/features/control/message/MessageControlExport.jsx (2)

6-6: Addition of cx utility improves class name management

Importing cx from styleUtils enhances the way class names are composed, improving readability and maintainability.


13-14: Refactored className assignment enhances flexibility

Using the classes variable with cx to combine style.content and style.contentColumnLayout allows for more dynamic class management and cleaner code.

Also applies to: 18-18

apps/client/src/features/control/message/MessageControl.tsx (3)

4-4: Refactored to use TimerControlsPreview component for better modularity

Importing and including TimerControlsPreview simplifies MessageControl by extracting timer preview logic into its own component, enhancing modularity and code organization.

Also applies to: 10-11


13-18: Updated InputRow components to reflect new timer and external message structure

Adjusting the InputRow components to use timer and external from useMessageControl aligns with the updated data structure and state management.

Also applies to: 21-26


13-18: Ensure timer blink and blackout functionality is preserved

The buttons for toggling the timer's blink and blackout features have been removed from this component. Please verify that this functionality is now correctly implemented within the TimerControlsPreview component or elsewhere to maintain existing features.

apps/client/src/features/editors/Editor.module.scss (2)

43-43: Updated border-radius to use CSS variable for consistency

Changing the border-radius to var(--editor--panel__br) ensures consistent styling across components and makes global updates simpler.


66-71: Added .contentColumnLayout class for improved layout management

The new .contentColumnLayout class enhances layout flexibility by providing a standardized column layout with consistent spacing and styling.

apps/client/src/features/control/message/MessageControl.module.scss (1)

1-75: Introduced new styles to enhance message control layout and responsiveness

The addition of multiple new classes and styling rules improves the visual structure and responsiveness of the message control component, enhancing user experience.

apps/client/src/features/control/message/TimerViewControl.tsx (1)

1-55: New TimerControlsPreview component enhances timer management UI

The creation of TimerControlsPreview provides a dedicated component for timer controls, improving code modularity and offering a clearer interface for managing timer features.

apps/server/src/services/message-service/messageUtils.ts (1)

33-33: Validation of 'secondary' property added to validateTimerMessage

Great job enhancing the validateTimerMessage function by adding validation for the 'secondary' property. This ensures that any incoming messages have a validated 'secondary' value, improving the robustness of message handling.

apps/server/src/services/message-service/MessageService.ts (2)

28-30: Refactoring to a functional init improves code clarity

Transitioning from a class-based init method to a functional approach simplifies the initialization logic and enhances readability.


35-40: Well-implemented getState function for state exposure

The new getState function cleanly exposes the internal message state, making it straightforward to retrieve the current state without class properties.

apps/client/src/features/control/message/InputRow.tsx (1)

55-63: Verify consistency between 'visible' and 'isPublic' field names

There appears to be a potential mismatch between the visible prop and the 'isPublic' field used in actionHandler. Verify whether the field should be 'visible' instead of 'isPublic' to maintain consistency and prevent confusion.

Run the following script to search for usages of actionHandler with 'isPublic' and 'visible' fields:

Verification successful

Usage of 'visible' and 'isPublic' is consistent and appropriate

After a thorough review of the codebase, I can confirm that the usage of 'visible' and 'isPublic' in the InputRow component is consistent and appropriate. Here's why:

  • 'visible' is used as a prop for the component and determines the UI state (whether the eye icon is open or closed).
  • 'isPublic' is used as the field name when updating the event data through the actionHandler.

This distinction is intentional and correct:

  • 'visible' relates to the UI representation of the public/private state.
  • 'isPublic' is the actual property name in the event data model, used consistently throughout the codebase for managing event visibility.

The actionHandler is correctly using 'isPublic' as the field name, which aligns with other parts of the codebase that deal with event data. This approach maintains a clear separation between UI state and data model properties.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Search for occurrences where 'actionHandler' updates 'isPublic' or 'visible' fields

# Test: Find all instances where 'actionHandler' is called with field 'isPublic' or 'visible'
rg "actionHandler\('update', \{ field: 'isPublic'" --type js
rg "actionHandler\('update', \{ field: 'visible'" --type js

Length of output: 148


Script:

#!/bin/bash
# Search for 'visible' and 'isPublic' in .tsx and .ts files
echo "Searching for 'visible' and 'isPublic':"
rg "visible|isPublic" --type ts --type tsx

# Look for the definition and usage of 'actionHandler'
echo -e "\nSearching for 'actionHandler' definition and usage:"
rg "function actionHandler|const actionHandler|actionHandler\s*=" --type ts --type tsx

# Search for 'TooltipActionBtn' component usage
echo -e "\nSearching for 'TooltipActionBtn' usage:"
rg "TooltipActionBtn" --type ts --type tsx

Length of output: 587


Script:

#!/bin/bash

# Find all .ts and .tsx files
echo "TypeScript and TypeScript React files:"
find . -type f \( -name "*.ts" -o -name "*.tsx" \)

# Search for relevant terms in .ts and .tsx files
echo -e "\nSearching for 'visible' and 'isPublic':"
grep -rn --include=\*.{ts,tsx} -E "visible|isPublic" .

echo -e "\nSearching for 'actionHandler':"
grep -rn --include=\*.{ts,tsx} -E "function actionHandler|const actionHandler|actionHandler\s*=" .

echo -e "\nSearching for 'TooltipActionBtn':"
grep -rn --include=\*.{ts,tsx} "TooltipActionBtn" .

Length of output: 52960

apps/client/src/features/rundown/event-block/EventBlockInner.tsx (1)

97-97: Simplification by removing unnecessary Tooltip around "UP NEXT"

Removing the Tooltip wrapper around the "UP NEXT" label simplifies the component and reduces unnecessary complexity, improving performance.

apps/client/src/common/hooks/useSocket.ts (3)

40-50: Approved: Addition of useMessagePreview hook

The new useMessagePreview hook correctly extracts state properties related to message visibility, content, and timer phases. This enhances the application's messaging capabilities by providing a centralized and efficient way to access these properties.


59-60: Approved: Addition of externalText and externalVisible setters

The new setters externalText and externalVisible in the setMessage object are properly implemented. They enable more granular control over external message properties, improving state management for external messages.


63-63: Approved: Addition of timerSecondary setter

The addition of timerSecondary to the setMessage object appropriately allows control over the secondary property of timer messages. This enhances the flexibility of message state management.

apps/client/src/features/viewers/timer/Timer.tsx (6)

51-51: Approved: Inclusion of auxTimer in TimerProps interface

Adding auxTimer: SimpleTimerState to the TimerProps interface allows the component to access auxiliary timer information. This is essential for implementing the new timer preview feature.


64-65: Approved: Destructuring auxTimer from props

Destructuring auxTimer from the props ensures that the auxiliary timer state is accessible within the Timer component. This is necessary for utilizing the auxiliary timer in the component logic.


137-148: Approved: Implementation of secondaryContent function

The secondaryContent function correctly determines the content to display based on the pres.secondary property. It prioritizes displaying the auxiliary timer when pres.secondary is 'aux' and falls back to the external message when available.


166-166: Approved: Adjusting timerFontSize based on secondaryContent

Reducing the timerFontSize when secondaryContent is present ensures that both the main timer and the secondary content are displayed properly without overlapping or layout issues.


208-211: Approved: Conditional rendering of secondary content

The external div correctly uses conditional classes and styling based on the presence of secondaryContent. This ensures that the secondary content is only displayed when available and maintains proper styling.


137-148: Issue: Incorrect usage of string in replace method

The replace method is using a string '/:/g' to represent a regular expression. In JavaScript, when using regular expressions with replace, you should pass a RegExp object instead of a string. Using a string will not replace all occurrences of the colon character.

Apply this diff to fix the regular expression:

- const stageTimerCharacters = display.replace('/:/g', '').length;
+ const stageTimerCharacters = display.replace(/:/g, '').length;

Likely invalid or redundant comment.

apps/client/src/features/viewers/ViewWrapper.tsx (2)

71-71: Variable Naming Consistency: Rename auxtimer1 to auxTimer for clarity.

As previously suggested, consider renaming auxtimer1 to auxTimer in the destructuring assignment to maintain consistent naming conventions and enhance code readability.


99-99: Variable Naming Consistency: Use auxTimer instead of auxtimer1 when passing as a prop.

Following the prior recommendation, after renaming auxtimer1 to auxTimer, pass it as auxTimer={auxTimer} to align the prop name with the variable name for consistency.

apps/server/src/services/message-service/messageUtils.ts Outdated Show resolved Hide resolved
apps/server/src/app.ts Show resolved Hide resolved
apps/server/src/app.ts Outdated Show resolved Hide resolved
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Outside diff range and nitpick comments (2)
apps/client/src/features/control/message/MessageControl.module.scss (1)

59-61: Clarify the purpose and usage of the .blackout class.

The .blackout class sets display: none, which hides the element. However, the purpose and usage of this class are not clear from the provided context. Please add a comment explaining when and why this class is used.

apps/server/src/api-integration/integration.controller.ts (1)

101-101: Reminder: Address the TODO comment.

The TODO comment indicates that the legacy message conversion logic should be removed after a specific date (20/09/2024). Please ensure to address this TODO comment and remove the legacy code when the specified date arrives.

Do you want me to open a GitHub issue to track this task?

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 5bc8e9e and 01d4684.

Files ignored due to path filters (3)
  • packages/types/src/definitions/runtime/MessageControl.type.ts is excluded by none and included by none
  • packages/types/src/index.ts is excluded by none and included by none
  • packages/types/src/utils/utils.type.ts is excluded by none and included by none
Files selected for processing (23)
  • apps/client/src/common/hooks/useSocket.ts (3 hunks)
  • apps/client/src/common/stores/runtime.ts (1 hunks)
  • apps/client/src/features/app-settings/panel/general-panel/ViewSettingsForm.tsx (1 hunks)
  • apps/client/src/features/control/message/InputRow.tsx (3 hunks)
  • apps/client/src/features/control/message/MessageControl.module.scss (1 hunks)
  • apps/client/src/features/control/message/MessageControl.tsx (1 hunks)
  • apps/client/src/features/control/message/MessageControlExport.jsx (1 hunks)
  • apps/client/src/features/control/message/TimerPreview.tsx (1 hunks)
  • apps/client/src/features/control/message/TimerViewControl.tsx (1 hunks)
  • apps/client/src/features/control/playback/aux-timer/AuxTimer.tsx (1 hunks)
  • apps/client/src/features/editors/Editor.module.scss (2 hunks)
  • apps/client/src/features/editors/EditorMixin.scss (2 hunks)
  • apps/client/src/features/rundown/event-block/EventBlockInner.tsx (2 hunks)
  • apps/client/src/features/viewers/ViewWrapper.tsx (2 hunks)
  • apps/client/src/features/viewers/timer/Timer.tsx (6 hunks)
  • apps/server/src/api-integration/tests/integration.legacy.test.ts (1 hunks)
  • apps/server/src/api-integration/integration.controller.ts (3 hunks)
  • apps/server/src/api-integration/integration.legacy.ts (1 hunks)
  • apps/server/src/app.ts (2 hunks)
  • apps/server/src/services/message-service/MessageService.ts (1 hunks)
  • apps/server/src/services/message-service/tests/MessageService.test.ts (3 hunks)
  • apps/server/src/services/message-service/tests/messageUtils.test.ts (1 hunks)
  • apps/server/src/services/message-service/messageUtils.ts (2 hunks)
Files skipped from review due to trivial changes (1)
  • apps/client/src/features/app-settings/panel/general-panel/ViewSettingsForm.tsx
Files skipped from review as they are similar to previous changes (11)
  • apps/client/src/features/control/message/InputRow.tsx
  • apps/client/src/features/control/message/MessageControlExport.jsx
  • apps/client/src/features/control/message/TimerPreview.tsx
  • apps/client/src/features/control/message/TimerViewControl.tsx
  • apps/client/src/features/control/playback/aux-timer/AuxTimer.tsx
  • apps/client/src/features/editors/Editor.module.scss
  • apps/client/src/features/editors/EditorMixin.scss
  • apps/client/src/features/rundown/event-block/EventBlockInner.tsx
  • apps/client/src/features/viewers/ViewWrapper.tsx
  • apps/client/src/features/viewers/timer/Timer.tsx
  • apps/server/src/app.ts
Additional context used
Biome
apps/server/src/services/message-service/MessageService.ts

[error] 52-52: Unexpected label.

Only loops should be labeled.
The use of labels for other statements is suspicious and unfamiliar.

(lint/suspicious/noConfusingLabels)


[error] 52-52: Unused label.

The label is not used by any break statement and continue statement.
Safe fix: Remove the unused label.

(lint/correctness/noUnusedLabels)

Additional comments not posted (42)
apps/server/src/services/message-service/__tests__/messageUtils.test.ts (2)

Line range hint 10-34: LGTM!

The test cases for the validateTimerMessage function are well-written and cover the expected behavior of the function, including the conversion of string values to boolean and the omission of keys not provided in the input payload.


5-5: Verify the impact of the change in validateMessage function's behavior.

The test case suggests that the validateMessage function now simply returns the input string without any validation or transformation. This is a significant change from the original behavior, where the function was expected to validate and convert the input payload to a Message object.

Please ensure that this change does not introduce any bugs or unexpected behavior in other parts of the codebase where this function is being used.

Run the following script to verify the usage of validateMessage function:

apps/server/src/services/message-service/__tests__/MessageService.test.ts (5)

1-1: LGTM!

The change from default import to namespace import for messageService is a valid stylistic preference and does not affect the functionality.


17-17: LGTM!

The change in the structure of the external property from an object to a string value is consistent with the modifications made to the expected output of the patch function in the test case.


23-23: LGTM!

The addition of the secondarySource property to the timer object in the expected output is consistent with the modifications made to the message object in the test case.


24-24: LGTM!

The change in the structure of the external property from an object to a string value in the expected output is consistent with the modifications made to the message object in the test case.


36-37: LGTM!

The addition of the secondarySource property to the timer object and the change in the structure of the external property to an empty string in the expected output are consistent with the modifications made in the previous test case.

apps/server/src/api-integration/__tests__/integration.legacy.test.ts (2)

4-16: LGTM!

The test case correctly verifies the behavior of the handleLegacyMessageConversion function when the payload is not a legacy message. It uses appropriate test inputs and assertions.


18-35: LGTM!

The test case correctly verifies the behavior of the handleLegacyMessageConversion function when the payload is a legacy message with an external message. It uses appropriate test inputs covering different scenarios and assertions.

apps/client/src/features/control/message/MessageControl.module.scss (9)

1-7: LGTM!

The .label class and its active state are well-defined using variables for consistency. The active state styling provides good visual feedback to the user.


10-14: LGTM!

The .previewContainer class uses a clean grid layout with a consistent gap between items. The 2:1 column ratio suggests a clear hierarchy of content.


16-22: LGTM!

The .preview class has a clean and centered layout. The use of a variable for the background color maintains consistency, and the relative positioning allows for flexibility in child element positioning.


30-37: LGTM!

The .eventStatus class is well-positioned as an overlay on the preview. The column layout with a small gap allows for compact display of multiple status indicators.


39-53: LGTM!

The .mainContent class has clear font styles and uses a CSS variable for easy color customization. The different color styles based on the data-phase attribute provide good visual indicators for different phases, with a reduced opacity for the none phase. The use of variables for colors maintains consistency.


55-57: LGTM!

The .secondaryContent class has a clear visual separation from the main content with a top border. The use of a variable for the border color maintains consistency.


63-66: LGTM!

The .timerIndicators class uses a column layout to stack its content vertically, which is appropriate for displaying multiple timer indicators.


68-74: LGTM!

The .statusIcon class has a clear default color and an active state color, both set using variables for consistency. The active state color provides a good visual indication when the data-active attribute is true.


76-78: LGTM!

The .divider class provides a clear visual separation between sections with a top border. The use of a variable for the border color maintains consistency.

apps/client/src/features/control/message/MessageControl.tsx (3)

6-14: LGTM!

The refactoring of the MessageControl component into smaller, more focused components is a great improvement in terms of code organization and separation of concerns. The removal of button controls also suggests a cleaner, more streamlined design.


16-29: LGTM!

The TimerMessageInput component is well-structured and utilizes the useTimerMessageInput hook effectively to manage the state of the timer message. The InputRow component is rendered with the appropriate props, making the code clean and easy to understand.


31-52: LGTM!

The ExternalInput component is well-structured and utilizes the useExternalMessageInput hook effectively to manage the state of the external message. The InputRow component is rendered with the appropriate props, and the toggleExternal function handles the visibility of the external message correctly.

apps/server/src/services/message-service/messageUtils.ts (3)

Line range hint 18-29: LGTM!

The addition of the secondarySource property validation improves the robustness of the timer message validation process. The function correctly handles the new property and ensures that it has a valid value.

Consider adding a test case to verify the behavior of the validateTimerMessage function with the new secondarySource property:

describe('validateTimerMessage', () => {
  // ...existing test cases

  it('should validate and coerce the secondarySource property', () => {
    const message = {
      text: 'Hello, world!',
      visible: true,
      blink: false,
      blackout: false,
      secondarySource: 'aux',
    };

    const result = validateTimerMessage(message);

    expect(result.secondarySource).toBe('aux');
  });

  it('should throw an error for an invalid secondarySource value', () => {
    const message = {
      text: 'Hello, world!',
      visible: true,
      blink: false,
      blackout: false,
      secondarySource: 'invalid',
    };

    expect(() => validateTimerMessage(message)).toThrowError('Invalid value received');
  });
});

35-37: LGTM!

The assertSecondary function provides a clear and concise way to validate the secondary value. It is used by the coerceSecondary function to ensure that the secondary value is valid.

Consider adding a test case to verify the behavior of the assertSecondary function:

describe('assertSecondary', () => {
  it('should return true for valid secondary values', () => {
    expect(assertSecondary('aux')).toBe(true);
    expect(assertSecondary('external')).toBe(true);
    expect(assertSecondary(null)).toBe(true);
  });

  it('should return false for invalid secondary values', () => {
    expect(assertSecondary('invalid')).toBe(false);
    expect(assertSecondary(undefined)).toBe(false);
    expect(assertSecondary(123)).toBe(false);
  });
});

42-47: LGTM, but consider enhancing the error message as suggested in the past review.

The coerceSecondary function provides a convenient way to coerce the secondary value to a valid value. However, the error message could be improved to provide more context about the invalid value and the expected valid values.

As suggested in the past review, apply this diff to improve the error message:

 function coerceSecondary(source: unknown): TimerMessage['secondarySource'] {
   if (!assertSecondary(source)) {
-    throw new Error('Invalid value received');
+    throw new Error(
+      `Invalid secondary value received: ${source}. Expected 'aux', 'external', or null.`
+    );
   }
   return source;
 }
apps/server/src/services/message-service/MessageService.ts (5)

7-13: LGTM!

The default value for the timer object is correctly defined as a constant with predefined properties.


15-16: LGTM!

The timer and external variables are correctly initialized using the default values.


24-26: LGTM!

The init function correctly initializes the message service by assigning the throttled publishFn to the throttledSet variable.


31-34: LGTM!

The clear function correctly resets the internal state of the message service by resetting the timer and external variables to their default values.


49-62: LGTM with a minor suggestion!

The patch function correctly updates the internal state based on the provided patch object, publishes the new state, and returns it.

However, as suggested by the static analysis hints and past review comments, the DEV label is unused and should be removed to clean up the code.

Apply this diff to remove the unused label:

-  // eslint-disable-next-line no-unused-labels -- dev code path
-  DEV: {
     if (throttledSet === null) {
       throw new Error('MessageService.patch() called before init()');
     }
-  }
Tools
Biome

[error] 52-52: Unexpected label.

Only loops should be labeled.
The use of labels for other statements is suspicious and unfamiliar.

(lint/suspicious/noConfusingLabels)


[error] 52-52: Unused label.

The label is not used by any break statement and continue statement.
Safe fix: Remove the unused label.

(lint/correctness/noUnusedLabels)

apps/client/src/common/stores/runtime.ts (1)

26-26: LGTM!

The addition of the secondarySource property aligns with the PR objective of exploring extra data for the timer feature. Initializing it to null is a valid approach for an optional property.

apps/client/src/common/hooks/useSocket.ts (5)

31-39: LGTM!

The useTimerViewControl hook is correctly extracting the relevant properties from the RuntimeStore for controlling the timer view. The property names match the RuntimeStore interface and the hook is correctly typed.


41-48: LGTM!

The useTimerMessageInput hook is correctly extracting the relevant properties from the RuntimeStore for the timer message input. The property names match the RuntimeStore interface and the hook is correctly typed.


50-57: LGTM!

The useExternalMessageInput hook is correctly extracting the relevant properties from the RuntimeStore for the external message input. The visibility state is correctly set based on the timer's secondary source, and the hook is correctly typed.


59-69: LGTM!

The useMessagePreview hook is correctly extracting the relevant properties from the RuntimeStore for the message preview. The various visibility and content checks are based on the appropriate conditions, and the hook is correctly typed.


76-76: LGTM!

The new externalText and timerSecondary methods in the setMessage object are correctly sending the respective payloads to the socket. The methods are correctly typed and the payload types match the expected types.

Also applies to: 79-80

apps/server/src/api-integration/integration.controller.ts (7)

1-3: LGTM!

The new imports are necessary for using the respective types and constants in the code. The import statements are correct.


4-5: LGTM!

The new import for DeepPartial from ts-essentials is likely intended to enhance type handling within the code. The import statement is correct.


8-8: LGTM!

The change from default import to namespace import for messageService allows for more flexible access to its exports. The import statement is correct.


18-18: LGTM!

The new import for handleLegacyMessageConversion from ./integration.legacy.js is likely used for processing legacy message format. The import statement is correct.


81-97: LGTM!

The new showExternal action handler enhances the functionality related to external message display. The use of DeepPartial<MessageState> ensures type safety while constructing the patch. The conditional logic correctly handles the case when the payload is a non-empty string, and the call to messageService.patch with the constructed patch is appropriate.


101-102: LGTM!

The TODO comment serves as a reminder to remove the legacy message conversion logic in the future, and the call to handleLegacyMessageConversion ensures that the legacy message format is handled appropriately. The changes ensure that the validation logic works with the migrated payload.


105-106: LGTM!

The conditional setting of the timer and external properties ensures that they are only included in the patch if present in the migrated payload. The use of validateTimerMessage and validateMessage functions ensures that the timer and external properties are validated before being included in the patch. The changes improve the robustness of the message handling logic by incorporating validation mechanisms.

@cpvalente cpvalente force-pushed the timer-preview branch 6 times, most recently from 1af12e4 to ed6b49a Compare September 21, 2024 11:35
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 1af12e4 and ed6b49a.

Files ignored due to path filters (4)
  • e2e/tests/features/201-message-control.spec.ts is excluded by none and included by none
  • packages/types/src/definitions/runtime/MessageControl.type.ts is excluded by none and included by none
  • packages/types/src/index.ts is excluded by none and included by none
  • packages/types/src/utils/utils.type.ts is excluded by none and included by none
Files selected for processing (25)
  • apps/client/src/common/hooks/useSocket.ts (3 hunks)
  • apps/client/src/common/stores/runtime.ts (1 hunks)
  • apps/client/src/features/app-settings/panel/general-panel/ViewSettingsForm.tsx (1 hunks)
  • apps/client/src/features/control/message/InputRow.tsx (3 hunks)
  • apps/client/src/features/control/message/MessageControl.module.scss (1 hunks)
  • apps/client/src/features/control/message/MessageControl.tsx (1 hunks)
  • apps/client/src/features/control/message/MessageControlExport.jsx (1 hunks)
  • apps/client/src/features/control/message/TimerPreview.tsx (1 hunks)
  • apps/client/src/features/control/message/TimerViewControl.tsx (1 hunks)
  • apps/client/src/features/control/playback/aux-timer/AuxTimer.tsx (1 hunks)
  • apps/client/src/features/editors/Editor.module.scss (2 hunks)
  • apps/client/src/features/editors/EditorMixin.scss (2 hunks)
  • apps/client/src/features/rundown/event-block/EventBlockInner.tsx (2 hunks)
  • apps/client/src/features/viewers/ViewWrapper.tsx (4 hunks)
  • apps/client/src/features/viewers/timer/Timer.scss (1 hunks)
  • apps/client/src/features/viewers/timer/Timer.tsx (7 hunks)
  • apps/client/src/theme/_viewerDefs.scss (1 hunks)
  • apps/server/src/api-integration/tests/integration.legacy.test.ts (1 hunks)
  • apps/server/src/api-integration/integration.controller.ts (3 hunks)
  • apps/server/src/api-integration/integration.legacy.ts (1 hunks)
  • apps/server/src/app.ts (3 hunks)
  • apps/server/src/services/message-service/MessageService.ts (1 hunks)
  • apps/server/src/services/message-service/tests/MessageService.test.ts (3 hunks)
  • apps/server/src/services/message-service/tests/messageUtils.test.ts (1 hunks)
  • apps/server/src/services/message-service/messageUtils.ts (3 hunks)
Files skipped from review due to trivial changes (1)
  • apps/client/src/features/app-settings/panel/general-panel/ViewSettingsForm.tsx
Files skipped from review as they are similar to previous changes (20)
  • apps/client/src/common/hooks/useSocket.ts
  • apps/client/src/common/stores/runtime.ts
  • apps/client/src/features/control/message/InputRow.tsx
  • apps/client/src/features/control/message/MessageControlExport.jsx
  • apps/client/src/features/control/message/TimerPreview.tsx
  • apps/client/src/features/control/message/TimerViewControl.tsx
  • apps/client/src/features/control/playback/aux-timer/AuxTimer.tsx
  • apps/client/src/features/editors/Editor.module.scss
  • apps/client/src/features/editors/EditorMixin.scss
  • apps/client/src/features/rundown/event-block/EventBlockInner.tsx
  • apps/client/src/features/viewers/ViewWrapper.tsx
  • apps/client/src/features/viewers/timer/Timer.scss
  • apps/client/src/features/viewers/timer/Timer.tsx
  • apps/client/src/theme/_viewerDefs.scss
  • apps/server/src/api-integration/tests/integration.legacy.test.ts
  • apps/server/src/api-integration/integration.controller.ts
  • apps/server/src/api-integration/integration.legacy.ts
  • apps/server/src/app.ts
  • apps/server/src/services/message-service/tests/MessageService.test.ts
  • apps/server/src/services/message-service/messageUtils.ts
Additional context used
Biome
apps/server/src/services/message-service/MessageService.ts

[error] 52-52: Unexpected label.

Only loops should be labeled.
The use of labels for other statements is suspicious and unfamiliar.

(lint/suspicious/noConfusingLabels)


[error] 52-52: Unused label.

The label is not used by any break statement and continue statement.
Safe fix: Remove the unused label.

(lint/correctness/noUnusedLabels)

Additional comments not posted (18)
apps/client/src/features/control/message/MessageControl.module.scss (10)

1-7: LGTM!

The .label class styles are well-structured and follow good practices by using variables for colors and sizes. The active state is also handled correctly.


10-14: LGTM!

The .previewContainer class creates a clean and responsive grid layout. The use of the fr unit for column sizes is a good choice for flexibility.


16-22: LGTM!

The .preview class styles the preview element effectively. The use of CSS Grid for centering and relative positioning for child elements is a good approach.


30-37: LGTM!

The .eventStatus class effectively positions and styles the event status element. The use of absolute positioning and flexbox for layout is a good choice.


39-53: LGTM!

The .mainContent class styles the main content effectively. The use of conditional styles based on data attributes is a good approach for handling different phases. The CSS variable for color override is also a nice touch.


55-57: LGTM!

The .secondaryContent class adds a simple border-top to separate the secondary content. The styles are clean and straightforward.


59-61: LGTM!

The .blackout class simply hides the blackout element by setting the display property to none. The styles are clean and straightforward.


63-66: LGTM!

The .timerIndicators class creates a flex container and stacks the child elements vertically. The styles are clean and straightforward.


68-74: LGTM!

The .statusIcon class styles the status icon effectively. The use of a conditional style based on the data-active attribute is a good approach for indicating the active state.


76-78: LGTM!

The .divider class adds a simple border-top to create a divider. The styles are clean and straightforward.

apps/client/src/features/control/message/MessageControl.tsx (4)

1-1: LGTM!

The new hooks useExternalMessageInput and useTimerMessageInput provide a cleaner separation of concerns for managing timer and external message states. The setMessage function will likely be used to update these states.


4-4: Looks good!

The new TimerControlsPreview component aligns with the PR objective of implementing a timer preview feature.


6-29: Great refactor!

The MessageControl component has been nicely refactored to render three distinct components, improving the organization of the code.

The TimerMessageInput component encapsulates the timer message functionality, using the useTimerMessageInput hook to manage its state. The InputRow component is reused to maintain consistency, and the changeHandler and actionHandler props provide a clean way to update the timer message state and visibility.


31-50: Nicely done!

The ExternalInput component encapsulates the external message functionality, using the useExternalMessageInput hook to manage its state. The toggleExternal function provides a clean way to toggle the visibility of the external message by updating the timerSecondary state.

The InputRow component is reused to maintain consistency, and the changeHandler and actionHandler props provide a straightforward way to update the external message state and visibility.

apps/server/src/services/message-service/MessageService.ts (4)

7-13: LGTM!

The default value for the timer object is correctly defined as a constant with predefined properties.


15-16: LGTM!

The timer and external variables are correctly initialized using the default values.


24-26: LGTM!

The init function correctly initializes the message service by assigning the throttled publishFn to the throttledSet variable.


31-34: LGTM!

The clear function correctly resets the internal state of the message service by resetting the timer and external variables to their default values.

Copy link
Collaborator

@alex-Arc alex-Arc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The legacy traslation works
haven't tryed the new stuff yet

@cpvalente
Copy link
Owner Author

The legacy traslation works

haven't tryed the new stuff yet

Nice, I have created a documentation page that hopefully helps

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Outside diff range and nitpick comments (7)
apps/client/src/features/control/message/MessageControl.module.scss (5)

1-7: LGTM! Consider using a variable for the active state color.

The .label class is well-structured and uses variables effectively. This aligns with the PR objective of improving the timer view.

For consistency, consider defining a variable for the active state color (currently $action-text-color) if it's used elsewhere in the application.


16-22: LGTM! Consider using a variable for the background color.

The .preview class effectively styles the preview area, contributing to the PR objective of creating a visually distinct timer preview.

For improved flexibility and consistency, consider using a variable for the background color (currently $ui-black) if it's used elsewhere in the application or might need to be changed in the future.


30-37: LGTM! Consider using variables for positioning and spacing values.

The .eventStatus class effectively positions and styles event status indicators, supporting the PR objective of displaying timer phases in the preview.

For improved maintainability, consider using variables for the positioning and spacing values (e.g., margin: 0.5rem 0.25rem; and gap: 0.25rem;) if these values are used consistently across the application.


39-53: LGTM! Effective use of data attributes for phase-based styling.

The .mainContent class effectively implements phase-based styling using data attributes, which aligns well with the PR objective of displaying different timer phases.

For consistency, consider using variables for the opacity value (opacity: $opacity-disabled;) and potentially for the font size and weight if these values are used elsewhere in the application.


68-74: LGTM! Consider using variables for colors.

The .statusIcon class effectively uses data attributes to manage the active state and change colors accordingly. This aligns well with the PR objective of displaying timer phases in the preview.

For consistency and maintainability, consider using variables for the colors ($gray-1000 and $active-indicator) if these colors are used elsewhere in the application.

apps/client/src/features/control/message/MessageControl.tsx (2)

1-14: Improved component structure and modularity

The refactoring of the MessageControl component and the introduction of new hooks (useExternalMessageInput and useTimerMessageInput) have significantly improved the code structure and modularity. This aligns well with the PR objectives of enhancing the timer view and creating a preview.

Consider adding a brief comment above the MessageControl function to describe its overall purpose and the role of each sub-component it renders. This would further improve code readability and maintainability.


16-29: Well-structured TimerMessageInput component

The introduction of the TimerMessageInput component effectively encapsulates the timer message input functionality. The use of the useTimerMessageInput hook for state management is a good practice, promoting better separation of concerns.

Consider adding prop types for the InputRow component to improve type safety and code documentation. This could be done using TypeScript interfaces or PropTypes if you're using JavaScript.

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between ed6b49a and 44e524c.

Files ignored due to path filters (4)
  • e2e/tests/features/201-message-control.spec.ts is excluded by none and included by none
  • packages/types/src/definitions/runtime/MessageControl.type.ts is excluded by none and included by none
  • packages/types/src/index.ts is excluded by none and included by none
  • packages/types/src/utils/utils.type.ts is excluded by none and included by none
Files selected for processing (25)
  • apps/client/src/common/hooks/useSocket.ts (3 hunks)
  • apps/client/src/common/stores/runtime.ts (1 hunks)
  • apps/client/src/features/app-settings/panel/general-panel/ViewSettingsForm.tsx (1 hunks)
  • apps/client/src/features/control/message/InputRow.tsx (3 hunks)
  • apps/client/src/features/control/message/MessageControl.module.scss (1 hunks)
  • apps/client/src/features/control/message/MessageControl.tsx (1 hunks)
  • apps/client/src/features/control/message/MessageControlExport.jsx (1 hunks)
  • apps/client/src/features/control/message/TimerPreview.tsx (1 hunks)
  • apps/client/src/features/control/message/TimerViewControl.tsx (1 hunks)
  • apps/client/src/features/control/playback/aux-timer/AuxTimer.tsx (1 hunks)
  • apps/client/src/features/editors/Editor.module.scss (2 hunks)
  • apps/client/src/features/editors/EditorMixin.scss (2 hunks)
  • apps/client/src/features/rundown/event-block/EventBlockInner.tsx (2 hunks)
  • apps/client/src/features/viewers/ViewWrapper.tsx (4 hunks)
  • apps/client/src/features/viewers/timer/Timer.scss (1 hunks)
  • apps/client/src/features/viewers/timer/Timer.tsx (7 hunks)
  • apps/client/src/theme/_viewerDefs.scss (1 hunks)
  • apps/server/src/api-integration/tests/integration.legacy.test.ts (1 hunks)
  • apps/server/src/api-integration/integration.controller.ts (3 hunks)
  • apps/server/src/api-integration/integration.legacy.ts (1 hunks)
  • apps/server/src/app.ts (3 hunks)
  • apps/server/src/services/message-service/MessageService.ts (1 hunks)
  • apps/server/src/services/message-service/tests/MessageService.test.ts (3 hunks)
  • apps/server/src/services/message-service/tests/messageUtils.test.ts (1 hunks)
  • apps/server/src/services/message-service/messageUtils.ts (3 hunks)
Files skipped from review as they are similar to previous changes (21)
  • apps/client/src/common/hooks/useSocket.ts
  • apps/client/src/common/stores/runtime.ts
  • apps/client/src/features/app-settings/panel/general-panel/ViewSettingsForm.tsx
  • apps/client/src/features/control/message/InputRow.tsx
  • apps/client/src/features/control/message/MessageControlExport.jsx
  • apps/client/src/features/control/message/TimerPreview.tsx
  • apps/client/src/features/control/message/TimerViewControl.tsx
  • apps/client/src/features/control/playback/aux-timer/AuxTimer.tsx
  • apps/client/src/features/editors/Editor.module.scss
  • apps/client/src/features/editors/EditorMixin.scss
  • apps/client/src/features/rundown/event-block/EventBlockInner.tsx
  • apps/client/src/features/viewers/ViewWrapper.tsx
  • apps/client/src/features/viewers/timer/Timer.scss
  • apps/client/src/features/viewers/timer/Timer.tsx
  • apps/client/src/theme/_viewerDefs.scss
  • apps/server/src/api-integration/tests/integration.legacy.test.ts
  • apps/server/src/api-integration/integration.controller.ts
  • apps/server/src/api-integration/integration.legacy.ts
  • apps/server/src/app.ts
  • apps/server/src/services/message-service/tests/MessageService.test.ts
  • apps/server/src/services/message-service/messageUtils.ts
Additional context used
Biome
apps/server/src/services/message-service/MessageService.ts

[error] 52-52: Unexpected label.

Only loops should be labeled.
The use of labels for other statements is suspicious and unfamiliar.

(lint/suspicious/noConfusingLabels)


[error] 52-52: Unused label.

The label is not used by any break statement and continue statement.
Safe fix: Remove the unused label.

(lint/correctness/noUnusedLabels)

Additional comments not posted (13)
apps/server/src/services/message-service/__tests__/messageUtils.test.ts (2)

Line range hint 9-38: Consider consistency between validateMessage and validateTimerMessage

While the tests for validateTimerMessage remain unchanged, the significant alterations to validateMessage create a potential inconsistency:

  1. validateMessage now appears to handle simple strings, while validateTimerMessage still processes complex objects.
  2. This discrepancy in behavior between similarly named functions could be confusing for developers.

Consider the following:

  • Should validateTimerMessage be updated to align with the new behavior of validateMessage?
  • If not, would it be beneficial to rename one or both functions to better reflect their distinct purposes?
  • Is there a reason for maintaining different validation approaches for messages and timer messages?

To better understand the relationship between these functions, please run the following script:

#!/bin/bash
# Search for the implementation of validateMessage and validateTimerMessage
rg --type typescript "export function validate(Message|TimerMessage)" -C 5

Could you clarify the intended relationship between these two functions and whether any further alignment or differentiation is planned?


Line range hint 1-7: Significant changes to validateMessage function behavior require clarification

The modifications to the validateMessage test suggest a fundamental change in the function's behavior:

  1. The function now appears to handle simple string inputs directly, rather than processing complex payload objects as before.
  2. Previous functionality, such as boolean conversions and handling of partial payloads, seems to have been removed.

These changes raise several concerns:

  • Has the purpose of the validateMessage function changed? If so, consider renaming it to better reflect its new behavior.
  • Is the simplification intentional, or has some functionality been inadvertently lost?
  • Are there any implications for existing code that may depend on the previous behavior?

To better understand the extent of these changes, please run the following script to check for other usages of validateMessage:

Could you provide more context on the rationale behind these changes and confirm if any related updates are needed in other parts of the codebase?

apps/client/src/features/control/message/MessageControl.module.scss (6)

10-13: LGTM! Effective use of grid layout for the preview container.

The .previewContainer class uses grid layout effectively to create a structured preview, which aligns well with the PR objective of creating a timer preview.


55-57: LGTM! Clear visual separation for secondary content.

The .secondaryContent class effectively separates secondary content with a top border, using a variable for color consistency.


59-61: Clarify the intended use of the .blackout class.

The .blackout class is currently set to display: none;. Could you provide more context on its intended use? If it's for future functionality, consider adding a TODO comment to explain its purpose.


63-66: LGTM! Effective use of flexbox for timer indicators.

The .timerIndicators class uses flexbox to create a column layout, which is appropriate for organizing timer indicators. This aligns with the PR objective of creating a timer preview with phase indicators.


76-78: LGTM! Clear visual divider.

The .divider class effectively creates a visual separator using a top border, with a variable used for color consistency.


1-78: Overall, the changes effectively support the PR objectives.

The modifications to MessageControl.module.scss significantly enhance the structure and visual presentation of the timer preview. The new classes for preview container, main content, status indicators, and various UI elements align well with the PR objectives of improving the timer view and creating a preview with phase indicators.

The consistent use of variables, data attributes for state management, and modern CSS techniques (like grid and flexbox) contribute to a more maintainable and flexible stylesheet. These changes should greatly improve the user experience when interacting with the timer functionality.

apps/server/src/services/message-service/MessageService.ts (5)

1-18: LGTM: Imports and default values are well-structured

The imports, default values, and global variables are appropriately defined for the new functional approach. The use of DeepPartial from 'ts-essentials' is a good practice for flexible type definitions in the patch function.


20-26: LGTM: Well-implemented initialization function

The init function is well-documented and correctly sets up a throttled publish function. This approach is good for managing state updates efficiently.


28-34: LGTM: Clear function effectively resets state

The clear function is well-implemented, using the spread operator to create a new object for the timer state and resetting both timer and external states. This approach ensures a clean state reset.


36-44: LGTM: GetState function provides comprehensive state

The getState function is well-implemented, returning a complete view of the current message state by combining both timer and external states. Its simplicity and clarity are commendable.


1-62: Overall: Excellent refactoring to functional approach

The refactoring of MessageService.ts from a class-based structure to a functional approach is well-executed. The new functions (init, clear, getState, and patch) are well-implemented and documented. The state management is consistent and efficient, using appropriate TypeScript features like DeepPartial for flexible updates.

The only minor issue was the unused DEV label in the patch function, which has been addressed in a previous comment.

This refactoring improves code clarity and maintainability, aligning well with modern JavaScript/TypeScript practices. Great job on the implementation!

Tools
Biome

[error] 52-52: Unexpected label.

Only loops should be labeled.
The use of labels for other statements is suspicious and unfamiliar.

(lint/suspicious/noConfusingLabels)


[error] 52-52: Unused label.

The label is not used by any break statement and continue statement.
Safe fix: Remove the unused label.

(lint/correctness/noUnusedLabels)

@alex-Arc
Copy link
Collaborator

for this
image
to work we need to implement some url encode/decodeing
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURI

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Outside diff range and nitpick comments (6)
apps/client/src/features/control/message/MessageControl.tsx (1)

1-4: Remove unused import

The InputRow import is not used in this file. Consider removing it to keep the imports clean and avoid confusion.

Apply this change:

-import InputRow from './InputRow';
apps/client/src/features/control/message/MessageControl.module.scss (5)

10-13: LGTM: Effective use of CSS Grid for layout

The .previewContainer class makes good use of CSS Grid for layout, with a sensible 2:1 column ratio. The use of variables for spacing is commendable.

Consider adding a comment explaining the purpose of the 2:1 ratio for better maintainability:

.previewContainer {
  display: grid;
  gap: $element-spacing;
  // 2:1 ratio for main content and sidebar
  grid-template-columns: 2fr 1fr;
}

24-38: LGTM: Well-implemented corner element with hover effects

The .corner class effectively creates a diagonal corner element with smooth hover transitions. The use of variables for colors and transition time is commendable.

Consider adding a focus state alongside the hover state for better keyboard accessibility:

.corner {
  // ... existing styles ...

  &:hover,
  &:focus {
    color: $ontime-color;
  }
}

46-53: LGTM with suggestion: Consider using variables for consistency

The .eventStatus class is well-structured for overlaying status information. The use of flexbox for layout is appropriate.

Consider using variables for the margin and gap values to maintain consistency with the rest of the stylesheet:

.eventStatus {
  position: absolute;
  left: 0;
  margin: $small-spacing $extra-small-spacing;
  display: flex;
  flex-direction: column;
  gap: $extra-small-spacing;
}

You may need to define these new variables ($small-spacing and $extra-small-spacing) if they don't already exist.


55-69: LGTM: Well-structured .mainContent class with dynamic styling

The .mainContent class is well-implemented with good use of CSS custom properties for color overrides and data-attributes for different phases. This approach allows for flexible and maintainable styling.

Consider using a Sass map for the phase colors to improve maintainability:

$phase-colors: (
  'pending': $ontime-roll,
  'overtime': $playback-negative,
  'none': rgba($ui-white, $opacity-disabled)
);

.mainContent {
  // ... existing styles ...

  @each $phase, $color in $phase-colors {
    &[data-phase='#{$phase}'] {
      color: $color;
    }
  }
}

This approach makes it easier to add or modify phases in the future.


71-93: LGTM: Clean implementation of utility classes

The new utility classes (.secondaryContent, .blackout, .timerIndicators, .statusIcon, and .divider) are well-structured and focused. The use of variables and data attributes for styling is commendable.

For the .blackout class, consider using a mixin or a utility class for hiding elements instead of directly setting display: none. This can make it easier to implement different hiding strategies in the future:

@mixin hidden {
  display: none;
}

// Or as a utility class
.hidden {
  display: none;
}

.blackout {
  @include hidden;
  // or
  @extend .hidden;
}

This approach provides more flexibility if you need to change how elements are hidden in the future.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between aef92e0 and bfd27da.

🔇 Files ignored due to path filters (4)
  • e2e/tests/features/201-message-control.spec.ts is excluded by none and included by none
  • packages/types/src/definitions/runtime/MessageControl.type.ts is excluded by none and included by none
  • packages/types/src/index.ts is excluded by none and included by none
  • packages/types/src/utils/utils.type.ts is excluded by none and included by none
📒 Files selected for processing (25)
  • apps/client/src/common/hooks/useSocket.ts (3 hunks)
  • apps/client/src/common/stores/runtime.ts (1 hunks)
  • apps/client/src/features/app-settings/panel/general-panel/ViewSettingsForm.tsx (1 hunks)
  • apps/client/src/features/control/message/InputRow.tsx (3 hunks)
  • apps/client/src/features/control/message/MessageControl.module.scss (1 hunks)
  • apps/client/src/features/control/message/MessageControl.tsx (1 hunks)
  • apps/client/src/features/control/message/MessageControlExport.jsx (1 hunks)
  • apps/client/src/features/control/message/TimerPreview.tsx (1 hunks)
  • apps/client/src/features/control/message/TimerViewControl.tsx (1 hunks)
  • apps/client/src/features/control/playback/aux-timer/AuxTimer.tsx (1 hunks)
  • apps/client/src/features/editors/Editor.module.scss (2 hunks)
  • apps/client/src/features/editors/EditorMixin.scss (2 hunks)
  • apps/client/src/features/rundown/event-block/EventBlockInner.tsx (2 hunks)
  • apps/client/src/features/viewers/ViewWrapper.tsx (4 hunks)
  • apps/client/src/features/viewers/timer/Timer.scss (1 hunks)
  • apps/client/src/features/viewers/timer/Timer.tsx (7 hunks)
  • apps/client/src/theme/_viewerDefs.scss (1 hunks)
  • apps/server/src/api-integration/tests/integration.legacy.test.ts (1 hunks)
  • apps/server/src/api-integration/integration.controller.ts (3 hunks)
  • apps/server/src/api-integration/integration.legacy.ts (1 hunks)
  • apps/server/src/app.ts (3 hunks)
  • apps/server/src/services/message-service/MessageService.ts (1 hunks)
  • apps/server/src/services/message-service/tests/MessageService.test.ts (3 hunks)
  • apps/server/src/services/message-service/tests/messageUtils.test.ts (1 hunks)
  • apps/server/src/services/message-service/messageUtils.ts (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (21)
  • apps/client/src/common/hooks/useSocket.ts
  • apps/client/src/common/stores/runtime.ts
  • apps/client/src/features/app-settings/panel/general-panel/ViewSettingsForm.tsx
  • apps/client/src/features/control/message/InputRow.tsx
  • apps/client/src/features/control/message/MessageControlExport.jsx
  • apps/client/src/features/control/message/TimerPreview.tsx
  • apps/client/src/features/control/message/TimerViewControl.tsx
  • apps/client/src/features/control/playback/aux-timer/AuxTimer.tsx
  • apps/client/src/features/editors/Editor.module.scss
  • apps/client/src/features/editors/EditorMixin.scss
  • apps/client/src/features/rundown/event-block/EventBlockInner.tsx
  • apps/client/src/features/viewers/ViewWrapper.tsx
  • apps/client/src/features/viewers/timer/Timer.scss
  • apps/client/src/features/viewers/timer/Timer.tsx
  • apps/client/src/theme/_viewerDefs.scss
  • apps/server/src/api-integration/tests/integration.legacy.test.ts
  • apps/server/src/api-integration/integration.controller.ts
  • apps/server/src/api-integration/integration.legacy.ts
  • apps/server/src/app.ts
  • apps/server/src/services/message-service/tests/MessageService.test.ts
  • apps/server/src/services/message-service/messageUtils.ts
🧰 Additional context used
Biome
apps/server/src/services/message-service/MessageService.ts

[error] 52-52: Unexpected label.

Only loops should be labeled.
The use of labels for other statements is suspicious and unfamiliar.

(lint/suspicious/noConfusingLabels)


[error] 52-52: Unused label.

The label is not used by any break statement and continue statement.
Safe fix: Remove the unused label.

(lint/correctness/noUnusedLabels)

🔇 Additional comments not posted (13)
apps/server/src/services/message-service/__tests__/messageUtils.test.ts (2)

Line range hint 9-38: Consider reviewing overall message validation strategy

While the validateTimerMessage tests remain unchanged, they present a stark contrast to the simplified validateMessage test. This discrepancy raises questions about the consistency of message handling across the system.

Consider the following points:

  1. Review the relationship between validateMessage and validateTimerMessage. Should they have similar levels of complexity and validation?
  2. Evaluate whether the current split between general messages and timer messages is still appropriate given the changes to validateMessage.
  3. Consider creating a consistent interface for all types of messages, which could simplify testing and usage throughout the application.

To facilitate this review, it may be helpful to compare the implementations of both functions:

#!/bin/bash
# Compare implementations of validateMessage and validateTimerMessage
echo "validateMessage implementation:"
ast-grep --lang typescript --pattern 'function validateMessage($_) { $$$ }' -C 3
echo "\nvalidateTimerMessage implementation:"
ast-grep --lang typescript --pattern 'function validateTimerMessage($_) { $$$ }' -C 3

This comparison will help in deciding whether to align the behaviors of these functions or to maintain their distinct implementations with clear documentation of their differences.


Line range hint 1-7: Significant change in validateMessage behavior requires careful consideration

The test for validateMessage has been drastically simplified, suggesting a fundamental change in the function's behavior. Previously, it appeared to convert a payload object into a structured Message object, but now it seems to simply return the input string as-is.

This change raises several concerns:

  1. The new behavior may not align with the function name "validateMessage", as it no longer appears to perform any validation.
  2. The change could have significant implications for other parts of the system that rely on the validateMessage function.
  3. The single test case is insufficient to cover various scenarios and ensure the function behaves correctly for different inputs.

Consider the following actions:

  1. Review the changes made to the validateMessage function implementation to ensure they align with the intended behavior.
  2. Update the function name if it no longer performs validation (e.g., formatMessage or processMessage).
  3. Add more test cases to cover different scenarios, such as:
    • Empty string input
    • Non-string input
    • Edge cases relevant to the new implementation
  4. Update documentation and comments to reflect the new behavior.
  5. Review and update any code that depends on the old behavior of validateMessage.

To assess the impact of this change, run the following script to find other occurrences of validateMessage:

This will help identify areas of the codebase that may need to be updated due to the changed behavior.

apps/client/src/features/control/message/MessageControl.tsx (1)

6-14: Improved component structure

The refactoring of the MessageControl component has significantly improved its structure. By delegating responsibilities to sub-components, the code is now more modular and easier to maintain. This aligns well with the PR objectives of improving the timer view and creating a preview.

apps/server/src/services/message-service/MessageService.ts (6)

1-18: LGTM: Imports and default values are well-structured

The imports, type definitions, and default value initializations are clear and appropriate for the file's purpose. The use of a default timer structure and mutable variables for timer and external provides a good foundation for the message service.


20-26: LGTM: Well-implemented initialization function

The init function is concise and focused. It properly sets up the throttled publish function, which is a good practice for managing update frequency. The function signature is clear and well-typed.


28-34: LGTM: Clear function effectively resets state

The clear function properly resets both the timer and external states. The use of the spread operator for timer ensures a clean reset without any lingering references to the old state.


36-44: LGTM: GetState function correctly exposes internal state

The getState function is well-implemented, returning the current state of both external and timer messages. The return type is correctly specified as MessageState, ensuring type safety for consumers of this function.


1-62: Overall: Excellent refactoring to functional approach

The refactoring of MessageService.ts from a class-based structure to a functional approach is well-executed. This change enhances the clarity and maintainability of the code. Key improvements include:

  1. Clear separation of concerns with distinct functions for initialization, state management, and updates.
  2. Proper use of TypeScript for type safety throughout the file.
  3. Efficient state management with the use of default values and the patch function.
  4. Throttling of updates to prevent excessive publish calls.

The only minor issue (the unused DEV label) has been addressed in a previous comment. Overall, this refactoring aligns well with modern JavaScript/TypeScript practices and should improve the overall quality of the codebase.

🧰 Tools
Biome

[error] 52-52: Unexpected label.

Only loops should be labeled.
The use of labels for other statements is suspicious and unfamiliar.

(lint/suspicious/noConfusingLabels)


[error] 52-52: Unused label.

The label is not used by any break statement and continue statement.
Safe fix: Remove the unused label.

(lint/correctness/noUnusedLabels)


46-62: ⚠️ Potential issue

Remove unused DEV label and approve other changes

The patch function is well-implemented, correctly updating the internal state, publishing the new state, and returning it. However, the DEV label is unnecessary and should be removed to clean up the code.

Apply this diff to remove the unused label:

-  // eslint-disable-next-line no-unused-labels -- dev code path
-  DEV: {
-    if (throttledSet === null) {
-      throw new Error('MessageService.patch() called before init()');
-    }
-  }
+  if (throttledSet === null) {
+    throw new Error('MessageService.patch() called before init()');
+  }

The rest of the implementation looks good and is approved.

🧰 Tools
Biome

[error] 52-52: Unexpected label.

Only loops should be labeled.
The use of labels for other statements is suspicious and unfamiliar.

(lint/suspicious/noConfusingLabels)


[error] 52-52: Unused label.

The label is not used by any break statement and continue statement.
Safe fix: Remove the unused label.

(lint/correctness/noUnusedLabels)

apps/client/src/features/control/message/MessageControl.module.scss (4)

1-7: LGTM: Well-structured .label class

The new .label class is well-implemented with appropriate use of variables for consistency. The .active state provides good visual feedback.


16-22: LGTM: Well-structured .preview class

The .preview class is well-implemented, using grid for content centering and setting up relative positioning for potential absolutely positioned children. The use of variables for colors maintains consistency.


40-43: LGTM: Clean implementation of .options class

The .options class uses flexbox effectively for a column layout. The use of variables for spacing maintains consistency across the stylesheet.


1-93: Overall: Well-implemented styling for the new timer preview feature

The changes in this file successfully implement the styling required for the new timer preview feature, aligning well with the PR objectives. The use of modern CSS techniques (Grid, Flexbox) and variables is consistent and commendable, contributing to a maintainable and flexible stylesheet.

While there are a few minor suggestions for improvements (such as using variables for all spacing values and considering a Sass map for phase colors), the overall quality of the changes is high. The new classes are well-structured and focused, providing a solid foundation for the enhanced timer view.

Great job on implementing these styling changes!

Comment on lines +16 to +29
function TimerMessageInput() {
const { text, visible } = useTimerMessageInput();

export default function MessageControl() {
const message = useMessageControl();
const blink = message.timer.blink;
const blackout = message.timer.blackout;
return (
<InputRow
label='Timer Message'
placeholder='Message shown fullscreen in stage timer'
text={text}
visible={visible}
changeHandler={(newValue) => setMessage.timerText(newValue)}
actionHandler={() => setMessage.timerVisible(!visible)}
/>
);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Enhance TimerMessageInput component

The TimerMessageInput component effectively encapsulates the timer message input functionality. Consider the following improvements:

  1. Add error handling for the setMessage.timerText and setMessage.timerVisible calls.
  2. Consider using TypeScript to define prop types for better type safety.

Example implementation with error handling:

import { useState } from 'react';

function TimerMessageInput() {
  const { text, visible } = useTimerMessageInput();
  const [error, setError] = useState<string | null>(null);

  const handleChange = (newValue: string) => {
    try {
      setMessage.timerText(newValue);
      setError(null);
    } catch (err) {
      setError('Failed to update timer text');
      console.error(err);
    }
  };

  const handleVisibilityToggle = () => {
    try {
      setMessage.timerVisible(!visible);
      setError(null);
    } catch (err) {
      setError('Failed to toggle timer visibility');
      console.error(err);
    }
  };

  return (
    <>
      <InputRow
        label='Timer Message'
        placeholder='Message shown fullscreen in stage timer'
        text={text}
        visible={visible}
        changeHandler={handleChange}
        actionHandler={handleVisibilityToggle}
      />
      {error && <div className="error-message">{error}</div>}
    </>
  );
}

Comment on lines +31 to 51
function ExternalInput() {
const { text, visible } = useExternalMessageInput();

const toggleExternal = () => {
if (visible) {
setMessage.timerSecondary(null);
} else {
setMessage.timerSecondary('external');
}
};

return (
<div className={style.messageContainer}>
<InputRow
label='Timer'
placeholder='Message shown in stage timer'
text={message.timer.text}
visible={message.timer.visible}
changeHandler={(newValue) => setMessage.timerText(newValue)}
actionHandler={() => setMessage.timerVisible(!message.timer.visible)}
/>
<div className={style.buttonSection}>
<Button
size='sm'
className={`${blink ? style.blink : ''}`}
variant={blink ? 'ontime-filled' : 'ontime-subtle'}
leftIcon={blink ? <IoSunny size='1rem' /> : <IoSunnyOutline size='1rem' />}
onClick={() => setMessage.timerBlink(!blink)}
data-testid='toggle timer blink'
>
Blink
</Button>
<Button
size='sm'
className={style.blackoutButton}
variant={blackout ? 'ontime-filled' : 'ontime-subtle'}
leftIcon={blackout ? <IoEye size='1rem' /> : <IoEyeOffOutline size='1rem' />}
onClick={() => setMessage.timerBlackout(!blackout)}
data-testid='toggle timer blackout'
>
Blackout screen
</Button>
</div>
<InputRow
label='External Message (read only)'
placeholder={enDash}
readonly
text={message.external.text}
visible={message.external.visible}
changeHandler={noop}
actionHandler={noop}
/>
</div>
<InputRow
label='External Message'
placeholder='Message shown as secondary text in stage timer'
text={text}
visible={visible}
changeHandler={(newValue) => setMessage.externalText(newValue)}
actionHandler={toggleExternal}
/>
);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Enhance ExternalInput component

The ExternalInput component effectively handles the external message functionality. Consider the following improvements:

  1. Extract the toggleExternal function to a custom hook or use useCallback for better performance.
  2. Add error handling for the setMessage.timerSecondary and setMessage.externalText calls.
  3. Consider using TypeScript to define prop types for better type safety.
  4. Use a constant for the 'external' string to avoid magic strings.

Example implementation with improvements:

import { useCallback, useState } from 'react';

const EXTERNAL_MESSAGE_TYPE = 'external';

function useExternalMessageToggle(visible: boolean) {
  return useCallback(() => {
    try {
      setMessage.timerSecondary(visible ? null : EXTERNAL_MESSAGE_TYPE);
    } catch (err) {
      console.error('Failed to toggle external message:', err);
      // Consider adding user-facing error handling here
    }
  }, [visible]);
}

function ExternalInput() {
  const { text, visible } = useExternalMessageInput();
  const [error, setError] = useState<string | null>(null);
  const toggleExternal = useExternalMessageToggle(visible);

  const handleChange = (newValue: string) => {
    try {
      setMessage.externalText(newValue);
      setError(null);
    } catch (err) {
      setError('Failed to update external text');
      console.error(err);
    }
  };

  return (
    <>
      <InputRow
        label='External Message'
        placeholder='Message shown as secondary text in stage timer'
        text={text}
        visible={visible}
        changeHandler={handleChange}
        actionHandler={toggleExternal}
      />
      {error && <div className="error-message">{error}</div>}
    </>
  );
}

These changes improve the component's robustness and maintainability.

Comment on lines +1 to 51
import { setMessage, useExternalMessageInput, useTimerMessageInput } from '../../../common/hooks/useSocket';

import InputRow from './InputRow';
import TimerControlsPreview from './TimerViewControl';

import style from './MessageControl.module.scss';
export default function MessageControl() {
return (
<>
<TimerControlsPreview />
<TimerMessageInput />
<ExternalInput />
</>
);
}

const noop = () => undefined;
function TimerMessageInput() {
const { text, visible } = useTimerMessageInput();

export default function MessageControl() {
const message = useMessageControl();
const blink = message.timer.blink;
const blackout = message.timer.blackout;
return (
<InputRow
label='Timer Message'
placeholder='Message shown fullscreen in stage timer'
text={text}
visible={visible}
changeHandler={(newValue) => setMessage.timerText(newValue)}
actionHandler={() => setMessage.timerVisible(!visible)}
/>
);
}

function ExternalInput() {
const { text, visible } = useExternalMessageInput();

const toggleExternal = () => {
if (visible) {
setMessage.timerSecondary(null);
} else {
setMessage.timerSecondary('external');
}
};

return (
<div className={style.messageContainer}>
<InputRow
label='Timer'
placeholder='Message shown in stage timer'
text={message.timer.text}
visible={message.timer.visible}
changeHandler={(newValue) => setMessage.timerText(newValue)}
actionHandler={() => setMessage.timerVisible(!message.timer.visible)}
/>
<div className={style.buttonSection}>
<Button
size='sm'
className={`${blink ? style.blink : ''}`}
variant={blink ? 'ontime-filled' : 'ontime-subtle'}
leftIcon={blink ? <IoSunny size='1rem' /> : <IoSunnyOutline size='1rem' />}
onClick={() => setMessage.timerBlink(!blink)}
data-testid='toggle timer blink'
>
Blink
</Button>
<Button
size='sm'
className={style.blackoutButton}
variant={blackout ? 'ontime-filled' : 'ontime-subtle'}
leftIcon={blackout ? <IoEye size='1rem' /> : <IoEyeOffOutline size='1rem' />}
onClick={() => setMessage.timerBlackout(!blackout)}
data-testid='toggle timer blackout'
>
Blackout screen
</Button>
</div>
<InputRow
label='External Message (read only)'
placeholder={enDash}
readonly
text={message.external.text}
visible={message.external.visible}
changeHandler={noop}
actionHandler={noop}
/>
</div>
<InputRow
label='External Message'
placeholder='Message shown as secondary text in stage timer'
text={text}
visible={visible}
changeHandler={(newValue) => setMessage.externalText(newValue)}
actionHandler={toggleExternal}
/>
);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

Implement Error Handling and Remove Unused Imports

The verification process identified that the new components lack proper error handling mechanisms and there are unused imports within the apps/client/src/features/control/message/ directory.

To address these issues:

  1. Error Handling:

    • Implement try/catch blocks or other error handling strategies in the new components (TimerControlsPreview, TimerMessageInput, ExternalInput) to ensure robustness.
  2. Unused Imports:

    • Remove any unused import statements in the following files to maintain code cleanliness:
      • TimerViewControl.tsx
      • TimerPreview.tsx
      • InputRow.tsx
🔗 Analysis chain

Overall improvements and verification suggestion

The refactoring of MessageControl.tsx has significantly improved the code structure, modularity, and maintainability. The introduction of separate components for timer and external messages, along with the use of custom hooks, addresses the PR objectives of improving the timer view and creating a preview.

To ensure these changes don't introduce any regressions and fully address the confusion reported in issue #1024, consider the following:

  1. Implement comprehensive unit tests for the new components and hooks.
  2. Conduct thorough integration testing to verify the interaction between these components.
  3. Update the documentation to reflect the new structure and functionality.

Run the following script to verify the implementation:

This script will help ensure that the old hook has been fully replaced, the new components are used correctly, error handling is implemented, and there are no leftover unused imports.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the implementation of new components and hooks

# Test: Check for any remaining uses of the old useMessageControl hook
rg -g "*.ts" -g "*.tsx" "useMessageControl"

# Test: Verify that TimerControlsPreview, TimerMessageInput, and ExternalInput are used correctly
rg -g "*.ts" -g "*.tsx" "<(TimerControlsPreview|TimerMessageInput|ExternalInput)\s*/?>" -A 5

# Test: Check for proper implementation of error handling in the new components
rg -g "*.ts" -g "*.tsx" "(try|catch|error)" apps/client/src/features/control/message/

# Test: Verify the usage of new hooks
rg -g "*.ts" -g "*.tsx" "use(ExternalMessageInput|TimerMessageInput)"

# Test: Check for any unused imports or components
rg -g "*.ts" -g "*.tsx" "import.*from.*" apps/client/src/features/control/message/ | grep -vE "(useExternalMessageInput|useTimerMessageInput|TimerControlsPreview)"

Length of output: 4410

@cpvalente cpvalente merged commit 8a5cef7 into master Sep 27, 2024
4 checks passed
@cpvalente cpvalente deleted the timer-preview branch September 27, 2024 18:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Count Up and Clock not clear in the editor timer
2 participants