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(hotkeys): Migrate hotkeys to customization service and fix issues with overrides #4777

Merged
merged 16 commits into from
Feb 25, 2025

Conversation

sedghi
Copy link
Member

@sedghi sedghi commented Feb 10, 2025

Hotkeys

Key Changes:

  • Hotkeys are no longer defined in mode factory via hotkeys: [...hotkeys.defaults.hotkeyBindings]
  • Hotkeys are now managed through the customizationService under the key ohif.hotkeyBindings
  • Default hotkeys are set automatically and can be customized using the customization service
  • User-defined hotkey preferences are now stored in a new format in localStorage
  • The HotkeysManager has undergone significant updates including better handling of defaults, key persistence, and cleanup

Migration Steps:

1. Remove hotkeys array from mode factory definition

Before:

- function modeFactory({ modeConfiguration }) {
-   return {
-     id: 'basic',
-     // ... other configuration
-     hotkeys: [...hotkeys.defaults.hotkeyBindings],
-   };
- }

After:

+ function modeFactory({ modeConfiguration }) {
+   return {
+     id: 'basic',
+     // ... other configuration
+     // No hotkeys array necessary
+   };
+ }

2. Set custom hotkeys using the customization service

There are several methods to modify hotkeys using the customization service:

a. Completely replace all hotkeys using $set:

+ onModeEnter: function ({ servicesManager }) {
+   const { customizationService } = servicesManager.services;
+   customizationService.setCustomizations({
+     'ohif.hotkeyBindings': {
+       $set: [
+         {
+           commandName: 'setToolActive',
+           commandOptions: { toolName: 'Zoom' },
+           label: 'Zoom',
+           keys: ['z'],
+           isEditable: true,
+         },
+       ],
+     },
+   });

b. Add new hotkeys using $push:

+ onModeEnter: function ({ servicesManager }) {
+   const { customizationService } = servicesManager.services;
+   customizationService.setCustomizations({
+     'ohif.hotkeyBindings': {
+       $push: [
+         {
+           commandName: 'myCustomCommand',
+           label: 'My Custom Function',
+           keys: ['ctrl+m'],
+           isEditable: true,
+         },
+       ],
+     },
+   });
+}

4. Update configuration file if you were setting window.config.hotkeys

If you were previously defining hotkeys in your window.config.js file, it was not really
taken into account. So you can safely remove it now.

Before:

- window.config = {
-   // ...other config
-   hotkeys: [
-     {
-       commandName: 'incrementActiveViewport',
-       label: 'Next Viewport',
-       keys: ['right'],
-     },
-     // ...more hotkeys
-   ],
- };

After:

+ window.config = {
+   // ...other config
+ };

5. Be aware that user preferences are now handled differently

The new system automatically handles user-preferred hotkey mappings:

  • User hotkey preferences are stored in localStorage under the key user-preferred-keys
  • The format is a hash-based mapping rather than a full array of definitions
  • There's a migration utility that converts old preferences to the new format
  • You don't need to manually handle this, but be aware of it if you're accessing localStorage directly

Tours

1. Update any direct references to window.config.tours

If you have any code that directly references window.config.tours, update it to use the customization service:

- const tours = window.config.tours;
+ const tours = customizationService.getCustomization('ohif.tours');

2. Use config update patterns for configuring tours

Before:

- window.config = {
-   tours: [
-     {
-       id: 'basicViewerTour',
-       route: '/viewer',
-       steps: [
-         // tour steps...
-       ],
-       tourOptions: {
-         // tour options...
-       },
-     },
-   ],
- };

After:

window.config = {
  customizationService: {
    'ohif.tours': {
      $set: [
        {
          id: 'basicViewerTour',
          route: '/viewer',
          steps: [
            // Your tour steps
          ],
        },
      ],
    },
  },
};

- Implemented undo and redo commands in Cornerstone extension
- Added Undo and Redo toolbar buttons in longitudinal mode
- Integrated hotkey bindings for Ctrl+Z and Ctrl+Y
- Created a utility function for generating hash values
- Updated HotkeysManager to improve hotkey handling
- Updated hotkey loading priority in Mode route
- Added support for global, mode-specific, and default hotkey configurations
- Improved HotkeysManager with better default binding and destroy methods
- Removed unnecessary logging and commented code
- Removed default hotkey bindings from core defaults
- Updated modes to remove hardcoded hotkey configurations
- Introduced customization service for managing hotkey bindings
- Added support for dynamic hotkey configuration in different modes
- Simplified hotkey management in Mode route and HotkeysManager
- Moved tours configuration from global config to customization service
- Updated Onboarding component to accept tours as a prop
- Removed tours configuration from default and Netlify config files
- Updated documentation for tour configuration
- Added tour customization module in default extension
- Renamed tour customization module to onboarding
- Refactored HotkeysManager to support user-preferred key bindings
- Simplified hotkey configuration in Mode route
- Added persistent storage for user-defined hotkey preferences
- Introduced more robust hotkey registration and management
Copy link

netlify bot commented Feb 10, 2025

Deploy Preview for ohif-dev canceled.

Name Link
🔨 Latest commit 47b299c
🔍 Latest deploy log https://app.netlify.com/sites/ohif-dev/deploys/67be0b82056e5f00088043de

Copy link

netlify bot commented Feb 10, 2025

Deploy Preview for ohif-platform-docs ready!

Name Link
🔨 Latest commit 47b299c
🔍 Latest deploy log https://app.netlify.com/sites/ohif-platform-docs/deploys/67be0b822c4f750008e7f272
😎 Deploy Preview https://deploy-preview-4777--ohif-platform-docs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@sedghi sedghi requested a review from wayfarer3130 February 10, 2025 23:36
@sedghi sedghi changed the title feat/undo redo fix(hotkeys): Migrate hotkeys to customization service and fix issues with overrides Feb 10, 2025
@@ -293,305 +293,4 @@ window.config = {
// ))
// },
// },
hotkeys: [
Copy link
Contributor

Choose a reason for hiding this comment

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

Do you need an example somewhere of how to add a custom binding? Probably something in e2e.js that demonstrates customizing the configuration bindings by adding a specific customization.

Copy link
Contributor

@wayfarer3130 wayfarer3130 left a comment

Choose a reason for hiding this comment

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

Can you add the changes:

Define the bindings for the extension in the extension
Define an array of customizations in the mode that combined define the hotkeys extensions to use
Define the default array of customizations in the extensions, and apply that as the default customizations to apply for a mode (so that modes do not need to define hotkey bindings customizations, but get something to apply by default)
Add a customization to the extensions in the e2e config that over-writes at least one hotkey to demonstrate how to use customization to add hotkey bindings.
Add at least one hotkey binding which has no keys, but is editable to demonstrate the ability to list hotkey commands which could be customized for the user should they choose to do so.
Generally I really like this change - I think it is a significant improvement

@sedghi
Copy link
Member Author

sedghi commented Feb 21, 2025

As we discussed,

  • I'll create issues for the requested scopes, specifically the extension-level hotkey customization, so we can mix and match them.
  • I'll also ensure the case for isEditable: true with an empty key works properly.

- Simplified HotkeysManager initialization by setting default values
- Added documentation for global and mode-specific hotkey customization
- Updated Onboarding component to handle optional tours
- Introduced sample customization for hotkey bindings in configuration
- Added default hotkey bindings in core defaults
- Implemented migration utility for legacy hotkey definitions
- Updated HotkeysManager to support migrating old hotkey configurations
- Simplified hotkey bindings customization in default extension
Copy link

cypress bot commented Feb 25, 2025

Viewers    Run #4832

Run Properties:  status check passed Passed #4832  •  git commit 47b299c2cd: fix test
Project Viewers
Branch Review feat/undo-redo
Run status status check passed Passed #4832
Run duration 02m 11s
Commit git commit 47b299c2cd: fix test
Committer sedghi
View all properties for this run ↗︎

Test results
Tests that failed  Failures 0
Tests that were flaky  Flaky 0
Tests that did not run due to a developer annotating a test with .skip  Pending 2
Tests that did not run due to a failure in a mocha hook  Skipped 0
Tests that passed  Passing 44
View all changes introduced in this branch ↗︎

- Added default window level presets to core defaults
- Modified hotkey binding method in basic test mode from $set to $push
- Removed unused hash generation utilities from core utils
@sedghi sedghi changed the title fix(hotkeys): Migrate hotkeys to customization service and fix issues with overrides feat(hotkeys): Migrate hotkeys to customization service and fix issues with overrides Feb 25, 2025
@sedghi sedghi merged commit 3e6913b into master Feb 25, 2025
20 checks passed
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.

2 participants