diff --git a/main.js b/main.js
index 62c530998..d1fc79aeb 100644
--- a/main.js
+++ b/main.js
@@ -1,4 +1,10 @@
-const { ipcMain: ipc, app, nativeTheme, Menu } = require('electron/main');
+const {
+ ipcMain: ipc,
+ app,
+ nativeTheme,
+ globalShortcut,
+ Menu,
+} = require('electron/main');
const { menubar } = require('menubar');
const { autoUpdater } = require('electron-updater');
const { onFirstRunMaybe } = require('./first-run');
@@ -122,6 +128,24 @@ app.whenReady().then(async () => {
}
});
+ ipc.on(
+ 'gitify:update-keyboard-shortcut',
+ (_, { enabled, keyboardShortcut }) => {
+ if (!enabled) {
+ globalShortcut.unregister(keyboardShortcut);
+ return;
+ }
+
+ globalShortcut.register(keyboardShortcut, () => {
+ if (mb.window.isVisible()) {
+ mb.hideWindow();
+ } else {
+ mb.showWindow();
+ }
+ });
+ },
+ );
+
ipc.on('gitify:update-auto-launch', (_, settings) => {
app.setLoginItemSettings(settings);
});
diff --git a/src/__mocks__/state-mocks.ts b/src/__mocks__/state-mocks.ts
index cc2848e69..b68810171 100644
--- a/src/__mocks__/state-mocks.ts
+++ b/src/__mocks__/state-mocks.ts
@@ -83,6 +83,7 @@ export const mockSettings: SettingsState = {
showAccountHostname: false,
delayNotificationState: false,
showPills: true,
+ keyboardShortcut: true,
};
export const mockState: GitifyState = {
diff --git a/src/context/App.test.tsx b/src/context/App.test.tsx
index f7cc61913..0f6ec61b6 100644
--- a/src/context/App.test.tsx
+++ b/src/context/App.test.tsx
@@ -379,6 +379,7 @@ describe('context/App.tsx', () => {
showAccountHostname: false,
delayNotificationState: false,
showPills: true,
+ keyboardShortcut: true,
} as SettingsState,
});
});
@@ -430,6 +431,7 @@ describe('context/App.tsx', () => {
showAccountHostname: false,
delayNotificationState: false,
showPills: true,
+ keyboardShortcut: true,
} as SettingsState,
});
});
diff --git a/src/context/App.tsx b/src/context/App.tsx
index 6114d3491..a9b6c33b6 100644
--- a/src/context/App.tsx
+++ b/src/context/App.tsx
@@ -31,7 +31,11 @@ import {
getUserData,
removeAccount,
} from '../utils/auth/utils';
-import { setAutoLaunch, updateTrayTitle } from '../utils/comms';
+import {
+ setAutoLaunch,
+ setKeyboardShortcut,
+ updateTrayTitle,
+} from '../utils/comms';
import Constants from '../utils/constants';
import { getNotificationCount } from '../utils/notifications';
import { clearState, loadState, saveState } from '../utils/storage';
@@ -57,6 +61,7 @@ export const defaultSettings: SettingsState = {
showAccountHostname: false,
delayNotificationState: false,
showPills: true,
+ keyboardShortcut: true,
};
interface AppContextState {
@@ -140,6 +145,10 @@ export const AppProvider = ({ children }: { children: ReactNode }) => {
}
}, [settings.showNotificationsCountInTray, notifications]);
+ useEffect(() => {
+ setKeyboardShortcut(settings.keyboardShortcut);
+ }, [settings.keyboardShortcut]);
+
const updateSetting = useCallback(
(name: keyof SettingsState, value: boolean | Theme) => {
if (name === 'openAtStartup') {
@@ -220,6 +229,7 @@ export const AppProvider = ({ children }: { children: ReactNode }) => {
}
if (existing.settings) {
+ setKeyboardShortcut(existing.settings.keyboardShortcut);
setSettings({ ...defaultSettings, ...existing.settings });
return existing.settings;
}
diff --git a/src/routes/Settings.test.tsx b/src/routes/Settings.test.tsx
index 399aaefe4..b316bb092 100644
--- a/src/routes/Settings.test.tsx
+++ b/src/routes/Settings.test.tsx
@@ -378,6 +378,31 @@ describe('routes/Settings.tsx', () => {
});
describe('System section', () => {
+ it('should toggle the keyboardShortcut checkbox', async () => {
+ await act(async () => {
+ render(
+