From a054fbce00fc4e703c2f41ff660f3150ba302923 Mon Sep 17 00:00:00 2001 From: Sanjai Kumar Date: Thu, 26 Sep 2024 18:03:36 +0530 Subject: [PATCH 1/2] Added Keybindings tab. --- .../Preferences/Keybindings/StyledWrapper.js | 46 ++++++++++++++ .../Preferences/Keybindings/index.js | 47 ++++++++++++++ .../src/components/Preferences/index.js | 12 +++- .../bruno-app/src/providers/Hotkeys/index.js | 33 +++++----- .../src/providers/Hotkeys/keyMappings.js | 63 +++++++++++++++++++ .../bruno-app/src/utils/common/platform.js | 15 +++++ 6 files changed, 199 insertions(+), 17 deletions(-) create mode 100644 packages/bruno-app/src/components/Preferences/Keybindings/StyledWrapper.js create mode 100644 packages/bruno-app/src/components/Preferences/Keybindings/index.js create mode 100644 packages/bruno-app/src/providers/Hotkeys/keyMappings.js diff --git a/packages/bruno-app/src/components/Preferences/Keybindings/StyledWrapper.js b/packages/bruno-app/src/components/Preferences/Keybindings/StyledWrapper.js new file mode 100644 index 0000000000..e129693887 --- /dev/null +++ b/packages/bruno-app/src/components/Preferences/Keybindings/StyledWrapper.js @@ -0,0 +1,46 @@ +import styled from 'styled-components'; + +const StyledWrapper = styled.div` + table { + width: 100%; + border-collapse: collapse; + + thead, + td { + border: 2px solid ${(props) => props.theme.table.border}; + } + + thead { + color: ${(props) => props.theme.table.thead.color}; + font-size: 1rem; + user-select: none; + } + + td { + padding: 4px 8px; + } + + thead th { + font-weight: 600; + padding: 10px; + text-align: left; + } + } + + .table-container { + max-height: 400px; + overflow-y: scroll; + } + + .key-button { + display: inline-block; + color: ${(props) => props.theme.colors.text.white}; + border-radius: 4px; + padding: 1px 5px; + font-family: monospace; + margin-right: 8px; + border: 1px solid #ccc; + } +`; + +export default StyledWrapper; diff --git a/packages/bruno-app/src/components/Preferences/Keybindings/index.js b/packages/bruno-app/src/components/Preferences/Keybindings/index.js new file mode 100644 index 0000000000..3b5930ae90 --- /dev/null +++ b/packages/bruno-app/src/components/Preferences/Keybindings/index.js @@ -0,0 +1,47 @@ +import StyledWrapper from './StyledWrapper'; +import React from 'react'; +import { useTheme } from 'providers/Theme'; +import { getKeyBindingsForOS } from 'providers/Hotkeys/keyMappings'; +import { getCurrentOS } from 'utils/common/platform'; + +const Keybindings = ({ close }) => { + const { storedTheme } = useTheme(); + const keyMapping = getKeyBindingsForOS(getCurrentOS()); + + return ( + +
+ + + + + + + + + {keyMapping ? ( + Object.entries(keyMapping).map(([action, { name, keys }], index) => ( + + + + + )) + ) : ( + + + + )} + +
CommandKeybinding
{name} + {keys.split('+').map((key, i) => ( +
+ {key} +
+ ))} +
No key bindings available
+
+
+ ); +}; + +export default Keybindings; diff --git a/packages/bruno-app/src/components/Preferences/index.js b/packages/bruno-app/src/components/Preferences/index.js index 03b1d9ef86..3635ca5a91 100644 --- a/packages/bruno-app/src/components/Preferences/index.js +++ b/packages/bruno-app/src/components/Preferences/index.js @@ -1,11 +1,14 @@ import Modal from 'components/Modal/index'; import classnames from 'classnames'; import React, { useState } from 'react'; + import Support from './Support'; import General from './General'; import Proxy from './ProxySettings'; +import Display from './Display'; +import Keybindings from './Keybindings'; + import StyledWrapper from './StyledWrapper'; -import Display from './Display/index'; const Preferences = ({ onClose }) => { const [tab, setTab] = useState('general'); @@ -30,6 +33,10 @@ const Preferences = ({ onClose }) => { return ; } + case 'keybindings': { + return ; + } + case 'support': { return ; } @@ -50,6 +57,9 @@ const Preferences = ({ onClose }) => {
setTab('proxy')}> Proxy
+
setTab('keybindings')}> + Keybindings +
setTab('support')}> Support
diff --git a/packages/bruno-app/src/providers/Hotkeys/index.js b/packages/bruno-app/src/providers/Hotkeys/index.js index 5b6bf1c007..41e71b4a27 100644 --- a/packages/bruno-app/src/providers/Hotkeys/index.js +++ b/packages/bruno-app/src/providers/Hotkeys/index.js @@ -10,6 +10,7 @@ import NewRequest from 'components/Sidebar/NewRequest'; import { sendRequest, saveRequest, saveCollectionRoot } from 'providers/ReduxStore/slices/collections/actions'; import { findCollectionByUid, findItemInCollection } from 'utils/collections'; import { closeTabs, switchTab } from 'providers/ReduxStore/slices/tabs'; +import { getKeyBindingsForActionAllOS } from './keyMappings'; export const HotkeysContext = React.createContext(); @@ -43,7 +44,7 @@ export const HotkeysProvider = (props) => { // save hotkey useEffect(() => { - Mousetrap.bind(['command+s', 'ctrl+s'], (e) => { + Mousetrap.bind([...getKeyBindingsForActionAllOS('save')], (e) => { if (isEnvironmentSettingsModalOpen) { console.log('todo: save environment settings'); } else { @@ -68,13 +69,13 @@ export const HotkeysProvider = (props) => { }); return () => { - Mousetrap.unbind(['command+s', 'ctrl+s']); + Mousetrap.unbind([...getKeyBindingsForActionAllOS('save')]); }; }, [activeTabUid, tabs, saveRequest, collections, isEnvironmentSettingsModalOpen]); // send request (ctrl/cmd + enter) useEffect(() => { - Mousetrap.bind(['command+enter', 'ctrl+enter'], (e) => { + Mousetrap.bind([...getKeyBindingsForActionAllOS('sendRequest')], (e) => { const activeTab = find(tabs, (t) => t.uid === activeTabUid); if (activeTab) { const collection = findCollectionByUid(collections, activeTab.collectionUid); @@ -95,13 +96,13 @@ export const HotkeysProvider = (props) => { }); return () => { - Mousetrap.unbind(['command+enter', 'ctrl+enter']); + Mousetrap.unbind([...getKeyBindingsForActionAllOS('sendRequest')]); }; }, [activeTabUid, tabs, saveRequest, collections]); // edit environments (ctrl/cmd + e) useEffect(() => { - Mousetrap.bind(['command+e', 'ctrl+e'], (e) => { + Mousetrap.bind([...getKeyBindingsForActionAllOS('editEnvironment')], (e) => { const activeTab = find(tabs, (t) => t.uid === activeTabUid); if (activeTab) { const collection = findCollectionByUid(collections, activeTab.collectionUid); @@ -115,13 +116,13 @@ export const HotkeysProvider = (props) => { }); return () => { - Mousetrap.unbind(['command+e', 'ctrl+e']); + Mousetrap.unbind([...getKeyBindingsForActionAllOS('editEnvironment')]); }; }, [activeTabUid, tabs, collections, setShowEnvSettingsModal]); // new request (ctrl/cmd + b) useEffect(() => { - Mousetrap.bind(['command+b', 'ctrl+b'], (e) => { + Mousetrap.bind([...getKeyBindingsForActionAllOS('newRequest')], (e) => { const activeTab = find(tabs, (t) => t.uid === activeTabUid); if (activeTab) { const collection = findCollectionByUid(collections, activeTab.collectionUid); @@ -135,13 +136,13 @@ export const HotkeysProvider = (props) => { }); return () => { - Mousetrap.unbind(['command+b', 'ctrl+b']); + Mousetrap.unbind([...getKeyBindingsForActionAllOS('newRequest')]); }; }, [activeTabUid, tabs, collections, setShowNewRequestModal]); // close tab hotkey useEffect(() => { - Mousetrap.bind(['command+w', 'ctrl+w'], (e) => { + Mousetrap.bind([...getKeyBindingsForActionAllOS('closeTab')], (e) => { dispatch( closeTabs({ tabUids: [activeTabUid] @@ -152,13 +153,13 @@ export const HotkeysProvider = (props) => { }); return () => { - Mousetrap.unbind(['command+w', 'ctrl+w']); + Mousetrap.unbind([...getKeyBindingsForActionAllOS('closeTab')]); }; }, [activeTabUid]); // Switch to the previous tab useEffect(() => { - Mousetrap.bind(['command+pageup', 'ctrl+pageup'], (e) => { + Mousetrap.bind([...getKeyBindingsForActionAllOS('switchToPreviousTab')], (e) => { dispatch( switchTab({ direction: 'pageup' @@ -169,13 +170,13 @@ export const HotkeysProvider = (props) => { }); return () => { - Mousetrap.unbind(['command+pageup', 'ctrl+pageup']); + Mousetrap.unbind([...getKeyBindingsForActionAllOS('switchToPreviousTab')]); }; }, [dispatch]); // Switch to the next tab useEffect(() => { - Mousetrap.bind(['command+pagedown', 'ctrl+pagedown'], (e) => { + Mousetrap.bind([...getKeyBindingsForActionAllOS('switchToNextTab')], (e) => { dispatch( switchTab({ direction: 'pagedown' @@ -186,13 +187,13 @@ export const HotkeysProvider = (props) => { }); return () => { - Mousetrap.unbind(['command+pagedown', 'ctrl+pagedown']); + Mousetrap.unbind([...getKeyBindingsForActionAllOS('switchToNextTab')]); }; }, [dispatch]); // Close all tabs useEffect(() => { - Mousetrap.bind(['command+shift+w', 'ctrl+shift+w'], (e) => { + Mousetrap.bind([...getKeyBindingsForActionAllOS('closeAllTabs')], (e) => { const activeTab = find(tabs, (t) => t.uid === activeTabUid); if (activeTab) { const collection = findCollectionByUid(collections, activeTab.collectionUid); @@ -211,7 +212,7 @@ export const HotkeysProvider = (props) => { }); return () => { - Mousetrap.unbind(['command+shift+w', 'ctrl+shift+w']); + Mousetrap.unbind([...getKeyBindingsForActionAllOS('closeAllTabs')]); }; }, [activeTabUid, tabs, collections, dispatch]); diff --git a/packages/bruno-app/src/providers/Hotkeys/keyMappings.js b/packages/bruno-app/src/providers/Hotkeys/keyMappings.js new file mode 100644 index 0000000000..1a65b028b3 --- /dev/null +++ b/packages/bruno-app/src/providers/Hotkeys/keyMappings.js @@ -0,0 +1,63 @@ +const KeyMapping = { + save: { mac: 'command+s', windows: 'ctrl+s', linux: 'ctrl+s', name: 'Save' }, + sendRequest: { mac: 'command+enter', windows: 'ctrl+enter', linux: 'ctrl+enter', name: 'Send Request' }, + editEnvironment: { mac: 'command+e', windows: 'ctrl+e', linux: 'ctrl+e', name: 'Edit Environment' }, + newRequest: { mac: 'command+b', windows: 'ctrl+b', linux: 'ctrl+b', name: 'New Request' }, + closeTab: { mac: 'command+w', windows: 'ctrl+w', linux: 'ctrl+w', name: 'Close Tab' }, + openPreferences: { mac: 'command+,', windows: 'ctrl+,', linux: 'ctrl+,', name: 'Open Preferences' }, + minimizeWindow: { + mac: 'command+Shift+Q', + windows: 'control+Shift+Q', + linux: 'control+Shift+Q', + name: 'Minimize Window' + }, + switchToPreviousTab: { + mac: 'command+pageup', + windows: 'ctrl+pageup', + linux: 'ctrl+pageup', + name: 'Switch to Previous Tab' + }, + switchToNextTab: { + mac: 'command+pagedown', + windows: 'ctrl+pagedown', + linux: 'ctrl+pagedown', + name: 'Switch to Next Tab' + }, + closeAllTabs: { mac: 'command+shift+w', windows: 'ctrl+shift+w', linux: 'ctrl+shift+w', name: 'Close All Tabs' } +}; + +/** + * Retrieves the key bindings for a specific operating system. + * + * @param {string} os - The operating system (e.g., 'mac', 'windows', 'linux'). + * @returns {Object} An object containing the key bindings for the specified OS. + */ +export const getKeyBindingsForOS = (os) => { + const keyBindings = {}; + for (const [action, { name, ...keys }] of Object.entries(KeyMapping)) { + if (keys[os]) { + keyBindings[action] = { + keys: keys[os], + name + }; + } + } + return keyBindings; +}; + +/** + * Retrieves the key bindings for a specific action across all operating systems. + * + * @param {string} action - The action for which to retrieve key bindings. + * @returns {Object|null} An object containing the key bindings for macOS, Windows, and Linux, or null if the action is not found. + */ +export const getKeyBindingsForActionAllOS = (action) => { + const actionBindings = KeyMapping[action]; + + if (!actionBindings) { + console.warn(`Action "${action}" not found in KeyMapping.`); + return null; + } + + return [actionBindings.mac, actionBindings.windows, actionBindings.linux]; +}; diff --git a/packages/bruno-app/src/utils/common/platform.js b/packages/bruno-app/src/utils/common/platform.js index ddfdb3a1fc..d8eb7f211a 100644 --- a/packages/bruno-app/src/utils/common/platform.js +++ b/packages/bruno-app/src/utils/common/platform.js @@ -45,6 +45,21 @@ export const isMacOS = () => { return osFamily.includes('os x'); }; +export const getCurrentOS = () => { + const os = platform.os; + const osFamily = os.family.toLowerCase(); + + if (osFamily.includes('windows')) { + return 'windows'; + } + + if (osFamily.includes('os x')) { + return 'mac'; + } + + return 'linux'; +}; + export const PATH_SEPARATOR = isWindowsOS() ? '\\' : '/'; export const getAppInstallDate = () => { From 0443271c72b8a9cf4dd4fe5a2633c2ced6212b83 Mon Sep 17 00:00:00 2001 From: Sanjai Kumar Date: Thu, 26 Sep 2024 18:58:14 +0530 Subject: [PATCH 2/2] Minor Refactoring --- .../Preferences/Keybindings/index.js | 6 ++--- .../src/providers/Hotkeys/keyMappings.js | 23 ++++++++----------- .../bruno-app/src/utils/common/platform.js | 15 ------------ 3 files changed, 12 insertions(+), 32 deletions(-) diff --git a/packages/bruno-app/src/components/Preferences/Keybindings/index.js b/packages/bruno-app/src/components/Preferences/Keybindings/index.js index 3b5930ae90..d2bc918aa5 100644 --- a/packages/bruno-app/src/components/Preferences/Keybindings/index.js +++ b/packages/bruno-app/src/components/Preferences/Keybindings/index.js @@ -1,12 +1,10 @@ import StyledWrapper from './StyledWrapper'; import React from 'react'; -import { useTheme } from 'providers/Theme'; import { getKeyBindingsForOS } from 'providers/Hotkeys/keyMappings'; -import { getCurrentOS } from 'utils/common/platform'; +import { isMacOS } from 'utils/common/platform'; const Keybindings = ({ close }) => { - const { storedTheme } = useTheme(); - const keyMapping = getKeyBindingsForOS(getCurrentOS()); + const keyMapping = getKeyBindingsForOS(isMacOS() ? 'mac' : 'windows'); return ( diff --git a/packages/bruno-app/src/providers/Hotkeys/keyMappings.js b/packages/bruno-app/src/providers/Hotkeys/keyMappings.js index 1a65b028b3..05ad4531b9 100644 --- a/packages/bruno-app/src/providers/Hotkeys/keyMappings.js +++ b/packages/bruno-app/src/providers/Hotkeys/keyMappings.js @@ -1,35 +1,32 @@ const KeyMapping = { - save: { mac: 'command+s', windows: 'ctrl+s', linux: 'ctrl+s', name: 'Save' }, - sendRequest: { mac: 'command+enter', windows: 'ctrl+enter', linux: 'ctrl+enter', name: 'Send Request' }, - editEnvironment: { mac: 'command+e', windows: 'ctrl+e', linux: 'ctrl+e', name: 'Edit Environment' }, - newRequest: { mac: 'command+b', windows: 'ctrl+b', linux: 'ctrl+b', name: 'New Request' }, - closeTab: { mac: 'command+w', windows: 'ctrl+w', linux: 'ctrl+w', name: 'Close Tab' }, - openPreferences: { mac: 'command+,', windows: 'ctrl+,', linux: 'ctrl+,', name: 'Open Preferences' }, + save: { mac: 'command+s', windows: 'ctrl+s', name: 'Save' }, + sendRequest: { mac: 'command+enter', windows: 'ctrl+enter', name: 'Send Request' }, + editEnvironment: { mac: 'command+e', windows: 'ctrl+e', name: 'Edit Environment' }, + newRequest: { mac: 'command+b', windows: 'ctrl+b', name: 'New Request' }, + closeTab: { mac: 'command+w', windows: 'ctrl+w', name: 'Close Tab' }, + openPreferences: { mac: 'command+,', windows: 'ctrl+,', name: 'Open Preferences' }, minimizeWindow: { mac: 'command+Shift+Q', windows: 'control+Shift+Q', - linux: 'control+Shift+Q', name: 'Minimize Window' }, switchToPreviousTab: { mac: 'command+pageup', windows: 'ctrl+pageup', - linux: 'ctrl+pageup', name: 'Switch to Previous Tab' }, switchToNextTab: { mac: 'command+pagedown', windows: 'ctrl+pagedown', - linux: 'ctrl+pagedown', name: 'Switch to Next Tab' }, - closeAllTabs: { mac: 'command+shift+w', windows: 'ctrl+shift+w', linux: 'ctrl+shift+w', name: 'Close All Tabs' } + closeAllTabs: { mac: 'command+shift+w', windows: 'ctrl+shift+w', name: 'Close All Tabs' } }; /** * Retrieves the key bindings for a specific operating system. * - * @param {string} os - The operating system (e.g., 'mac', 'windows', 'linux'). + * @param {string} os - The operating system (e.g., 'mac', 'windows'). * @returns {Object} An object containing the key bindings for the specified OS. */ export const getKeyBindingsForOS = (os) => { @@ -49,7 +46,7 @@ export const getKeyBindingsForOS = (os) => { * Retrieves the key bindings for a specific action across all operating systems. * * @param {string} action - The action for which to retrieve key bindings. - * @returns {Object|null} An object containing the key bindings for macOS, Windows, and Linux, or null if the action is not found. + * @returns {Object|null} An object containing the key bindings for macOS, Windows, or null if the action is not found. */ export const getKeyBindingsForActionAllOS = (action) => { const actionBindings = KeyMapping[action]; @@ -59,5 +56,5 @@ export const getKeyBindingsForActionAllOS = (action) => { return null; } - return [actionBindings.mac, actionBindings.windows, actionBindings.linux]; + return [actionBindings.mac, actionBindings.windows]; }; diff --git a/packages/bruno-app/src/utils/common/platform.js b/packages/bruno-app/src/utils/common/platform.js index d8eb7f211a..ddfdb3a1fc 100644 --- a/packages/bruno-app/src/utils/common/platform.js +++ b/packages/bruno-app/src/utils/common/platform.js @@ -45,21 +45,6 @@ export const isMacOS = () => { return osFamily.includes('os x'); }; -export const getCurrentOS = () => { - const os = platform.os; - const osFamily = os.family.toLowerCase(); - - if (osFamily.includes('windows')) { - return 'windows'; - } - - if (osFamily.includes('os x')) { - return 'mac'; - } - - return 'linux'; -}; - export const PATH_SEPARATOR = isWindowsOS() ? '\\' : '/'; export const getAppInstallDate = () => {