From 36ef38be6a9b124dab9b08dca8e4bbf30b1edcd1 Mon Sep 17 00:00:00 2001 From: "dev.paramjot" <50148441+ParamjotSingh5@users.noreply.github.com> Date: Thu, 29 Aug 2024 11:12:28 +0530 Subject: [PATCH] feat(#736): Switch tabs with keyboard shortcut (#812) * feat(#736): Switch tabs with keyboard shortcut 1. Registered keyboard events in Hotkeys/index.js 2. Added logic for replacing `state.activeTabUid` to switch active tab as per keyboard event. 3. Maintained a stack `recentUsedTabsStack` for tab visit history and pop out on `Ctrl+Tab` keyboard event. * feat(#736): Switch tabs with keyboard shortcut Keeping this feature request only limited to CTRL+PGUP and CTRL_PGDN button clicks functionality. Hence removing logic for CTRL+TAB click functionality. * feat(#736): Switch tabs with keyboard shortcut clean up * feate(#827): Switch tabs with keyboard shortcut * Implimented logic of cyclic traversal of tabs array with % opreator. --------- Co-authored-by: Anoop M D --- .../bruno-app/src/providers/Hotkeys/index.js | 38 ++++++++++++++++++- .../src/providers/ReduxStore/slices/tabs.js | 21 ++++++++++ 2 files changed, 57 insertions(+), 2 deletions(-) diff --git a/packages/bruno-app/src/providers/Hotkeys/index.js b/packages/bruno-app/src/providers/Hotkeys/index.js index 53a0fc263..1b28b891b 100644 --- a/packages/bruno-app/src/providers/Hotkeys/index.js +++ b/packages/bruno-app/src/providers/Hotkeys/index.js @@ -9,7 +9,7 @@ import NetworkError from 'components/ResponsePane/NetworkError'; import NewRequest from 'components/Sidebar/NewRequest'; import { sendRequest, saveRequest } from 'providers/ReduxStore/slices/collections/actions'; import { findCollectionByUid, findItemInCollection } from 'utils/collections'; -import { closeTabs } from 'providers/ReduxStore/slices/tabs'; +import { closeTabs, switchTab } from 'providers/ReduxStore/slices/tabs'; export const HotkeysContext = React.createContext(); @@ -154,7 +154,41 @@ export const HotkeysProvider = (props) => { }; }, [activeTabUid]); - // close all tabs + // Switch to the previous tab + useEffect(() => { + Mousetrap.bind(['command+pageup', 'ctrl+pageup'], (e) => { + dispatch( + switchTab({ + direction: 'pageup' + }) + ); + + return false; // this stops the event bubbling + }); + + return () => { + Mousetrap.unbind(['command+pageup', 'ctrl+pageup']); + }; + }, [dispatch]); + + // Switch to the next tab + useEffect(() => { + Mousetrap.bind(['command+pagedown', 'ctrl+pagedown'], (e) => { + dispatch( + switchTab({ + direction: 'pagedown' + }) + ); + + return false; // this stops the event bubbling + }); + + return () => { + Mousetrap.unbind(['command+pagedown', 'ctrl+pagedown']); + }; + }, [dispatch]); + + // Close all tabs useEffect(() => { Mousetrap.bind(['command+shift+w', 'ctrl+shift+w'], (e) => { const activeTab = find(tabs, (t) => t.uid === activeTabUid); diff --git a/packages/bruno-app/src/providers/ReduxStore/slices/tabs.js b/packages/bruno-app/src/providers/ReduxStore/slices/tabs.js index 7c7038280..935be6075 100644 --- a/packages/bruno-app/src/providers/ReduxStore/slices/tabs.js +++ b/packages/bruno-app/src/providers/ReduxStore/slices/tabs.js @@ -48,6 +48,26 @@ export const tabsSlice = createSlice({ focusTab: (state, action) => { state.activeTabUid = action.payload.uid; }, + switchTab: (state, action) => { + if (!state.tabs || !state.tabs.length) { + state.activeTabUid = null; + return; + } + + const direction = action.payload.direction; + + const activeTabIndex = state.tabs.findIndex((t) => t.uid === state.activeTabUid); + + let toBeActivatedTabIndex = 0; + + if (direction == 'pageup') { + toBeActivatedTabIndex = (activeTabIndex - 1 + state.tabs.length) % state.tabs.length; + } else if (direction == 'pagedown') { + toBeActivatedTabIndex = (activeTabIndex + 1) % state.tabs.length; + } + + state.activeTabUid = state.tabs[toBeActivatedTabIndex].uid; + }, updateRequestPaneTabWidth: (state, action) => { const tab = find(state.tabs, (t) => t.uid === action.payload.uid); @@ -111,6 +131,7 @@ export const tabsSlice = createSlice({ export const { addTab, focusTab, + switchTab, updateRequestPaneTabWidth, updateRequestPaneTab, updateResponsePaneTab,