Skip to content

Commit

Permalink
Allow customising certain keyboard shortcuts
Browse files Browse the repository at this point in the history
This allows customising next/previous service shortcuts, but opens the
door to using the same code and UI for customizing further shortcuts.

These particular shortcuts were requested to be customizable in the
github issue ferdium#53
  • Loading branch information
insidewhy authored and vraravam committed Oct 11, 2024
1 parent 1e55cee commit d513613
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 5 deletions.
26 changes: 26 additions & 0 deletions src/components/settings/settings/EditSettingsForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,10 @@ const messages = defineMessages({
id: 'settings.app.subheadlineDownloads',
defaultMessage: 'Downloads',
},
subheadlineShortcuts: {
id: 'settings.app.subheadlineShortcuts',
defaultMessage: 'Shortcuts',
},
cacheInfo: {
id: 'settings.app.cacheInfo',
defaultMessage: 'Ferdium cache is currently using {size} of disk space.',
Expand Down Expand Up @@ -1172,6 +1176,28 @@ class EditSettingsForm extends Component<IProps, IState> {
})}
</p>
</div>

<Hr />

<div className="settings__settings-group">
<H3>{intl.formatMessage(messages.subheadlineShortcuts)}</H3>

<Input
placeholder="Activate next service"
onChange={e => this.submit(e)}
{...form.$('shortcutActivateNextService').bind()}
/>

<Input
placeholder="Activate previous service"
onChange={e => this.submit(e)}
{...form.$('shortcutActivatePreviousService').bind()}
/>

<p className="settings__help">
{intl.formatMessage(messages.appRestartRequired)}
</p>
</div>
</div>
)}

Expand Down
9 changes: 8 additions & 1 deletion src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import ms from 'ms';

import { cmdOrCtrlShortcutKey, shiftKey } from './environment';

export const DEFAULT_ACCENT_COLOR = '#7367F0';

export const CHECK_INTERVAL = ms('1h'); // How often should we perform checks
Expand Down Expand Up @@ -326,7 +328,7 @@ export const FERDIUM_TRANSLATION = 'https://crowdin.com/project/ferdium-app';
export const FERDIUM_DEV_DOCS =
'https://github.com/ferdium/ferdium-recipes/blob/main/docs/integration.md';

export const FILE_SYSTEM_SETTINGS_TYPES = ['app', 'proxy'];
export const FILE_SYSTEM_SETTINGS_TYPES = ['app', 'proxy', 'shortcuts'];

export const LOCAL_SERVER = 'You are using Ferdium without a server';
export const SERVER_NOT_LOADED = 'Ferdium::SERVER_NOT_LOADED';
Expand Down Expand Up @@ -469,3 +471,8 @@ export const DEFAULT_SERVICE_SETTINGS = {
darkReaderContrast: 90,
darkReaderSepia: 10,
};

export const DEFAULT_SHORTCUTS = {
activateNextService: `${cmdOrCtrlShortcutKey()}+tab`,
activatePreviousService: `${cmdOrCtrlShortcutKey()}+${shiftKey()}+tab`,
};
31 changes: 31 additions & 0 deletions src/containers/settings/EditSettingsScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import type { StoresProps } from '../../@types/ferdium-components.types';
import type { FormFields } from '../../@types/mobx-form.types';
import {
DEFAULT_APP_SETTINGS,
DEFAULT_SHORTCUTS,
GOOGLE_TRANSLATOR_LANGUAGES,
HIBERNATION_STRATEGIES,
ICON_SIZES,
Expand Down Expand Up @@ -42,6 +43,7 @@ import ErrorBoundary from '../../components/util/ErrorBoundary';
import { importExportURL } from '../../api/apiBase';
import globalMessages from '../../i18n/globalMessages';
import { ifUndefined } from '../../jsUtils';
import { menuItems } from '../../lib/Menu';

const debug = require('../../preload-safe-debug')('Ferdium:EditSettingsScreen');

Expand Down Expand Up @@ -499,6 +501,11 @@ class EditSettingsScreen extends Component<
locale: settingsData.locale, // we need this info in the main process as well
};

const newShortcuts = {
activateNextService: settingsData.shortcutActivateNextService,
activatePreviousService: settingsData.shortcutActivatePreviousService,
};

const requiredRestartKeys = [
'webRTCIPHandlingPolicy',
'sentry',
Expand Down Expand Up @@ -539,6 +546,12 @@ class EditSettingsScreen extends Component<
data: newSettings,
});

settings.update({
type: 'shortcuts',
// TODO: The conversions might not be necessary once we convert to typescript
data: newShortcuts,
});

user.update({
userData: {
automaticUpdates: Boolean(settingsData.automaticUpdates),
Expand Down Expand Up @@ -1297,6 +1310,24 @@ class EditSettingsScreen extends Component<
default: DEFAULT_APP_SETTINGS.automaticUpdates,
type: 'checkbox',
},
shortcutActivateNextService: {
label: intl.formatMessage(menuItems.activateNextService),
value: ifUndefined<string>(
settings.all.shortcuts.activateNextService,
DEFAULT_SHORTCUTS.activateNextService,
),
default: DEFAULT_SHORTCUTS.activateNextService,
placeholder: DEFAULT_SHORTCUTS.activateNextService,
},
shortcutActivatePreviousService: {
label: intl.formatMessage(menuItems.activatePreviousService),
value: ifUndefined<string>(
settings.all.shortcuts.activatePreviousService,
DEFAULT_SHORTCUTS.activatePreviousService,
),
default: DEFAULT_SHORTCUTS.activatePreviousService,
placeholder: DEFAULT_SHORTCUTS.activatePreviousService,
},
},
};

Expand Down
1 change: 1 addition & 0 deletions src/i18n/locales/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,7 @@
"settings.app.subheadlineCache": "Cache",
"settings.app.subheadlineDownloads": "Downloads",
"settings.app.subheadlineFerdiumProfile": "Ferdium Profile",
"settings.app.subheadlineShortcuts": "Shortcuts",
"settings.app.subheadlineUserAgent": "User Agent",
"settings.app.todoServerInfo": "This server will be used for the \"Ferdium Todo\" feature.",
"settings.app.translationHelp": "Help us to translate Ferdium into your language.",
Expand Down
8 changes: 7 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@ import enforceMacOSAppLocation from './enforce-macos-app-location';

initializeRemote();

import { DEFAULT_APP_SETTINGS, DEFAULT_WINDOW_OPTIONS } from './config';
import {
DEFAULT_APP_SETTINGS,
DEFAULT_SHORTCUTS,
DEFAULT_WINDOW_OPTIONS,
} from './config';

import { altKey, isLinux, isMac, isWindows } from './environment';
import {
Expand Down Expand Up @@ -95,6 +99,7 @@ if (isWindows) {
// Initialize Settings
const settings = new Settings('app', DEFAULT_APP_SETTINGS);
const proxySettings = new Settings('proxy');
const shortcutSettings = new Settings('shortcuts', DEFAULT_SHORTCUTS);

const retrieveSettingValue = (key: string, defaultValue: boolean | string) =>
ifUndefined<boolean | string>(settings.get(key), defaultValue);
Expand Down Expand Up @@ -283,6 +288,7 @@ const createWindow = () => {
settings: {
app: settings,
proxy: proxySettings,
shortcuts: shortcutSettings,
},
trayIcon,
});
Expand Down
6 changes: 3 additions & 3 deletions src/lib/Menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ import { acceleratorString } from '../jsUtils';
import type Service from '../models/Service';
import type { RealStores } from '../stores';

const menuItems = defineMessages({
export const menuItems = defineMessages({
edit: {
id: 'menu.edit',
defaultMessage: 'Edit',
Expand Down Expand Up @@ -1102,7 +1102,7 @@ class FranzMenu implements StoresProps {
},
{
label: intl.formatMessage(menuItems.activateNextService),
accelerator: `${cmdOrCtrlShortcutKey()}+tab`,
accelerator: this.stores.settings.shortcuts.activateNextService,
click: () => this.actions.service.setActiveNext(),
visible: !cmdAltShortcutsVisibile,
},
Expand All @@ -1114,7 +1114,7 @@ class FranzMenu implements StoresProps {
},
{
label: intl.formatMessage(menuItems.activatePreviousService),
accelerator: `${cmdOrCtrlShortcutKey()}+${shiftKey()}+tab`,
accelerator: this.stores.settings.shortcuts.activatePreviousService,
click: () => this.actions.service.setActivePrev(),
visible: !cmdAltShortcutsVisibile,
},
Expand Down
7 changes: 7 additions & 0 deletions src/stores/SettingsStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import type { Actions } from '../actions/lib/actions';
import type { ApiInterface } from '../api';
import {
DEFAULT_APP_SETTINGS,
DEFAULT_SHORTCUTS,
FILE_SYSTEM_SETTINGS_TYPES,
LOCAL_SERVER,
} from '../config';
Expand All @@ -23,6 +24,7 @@ export default class SettingsStore extends TypedStore {
@observable _fileSystemSettingsCache = {
app: DEFAULT_APP_SETTINGS,
proxy: {},
shortcuts: DEFAULT_SHORTCUTS,
};

constructor(stores: Stores, api: ApiInterface, actions: Actions) {
Expand Down Expand Up @@ -126,6 +128,10 @@ export default class SettingsStore extends TypedStore {
);
}

@computed get shortcuts() {
return this._fileSystemSettingsCache.shortcuts || DEFAULT_SHORTCUTS;
}

@computed get stats() {
return (
localStorage.getItem('stats') || {
Expand All @@ -145,6 +151,7 @@ export default class SettingsStore extends TypedStore {
service: this.service,
stats: this.stats,
migration: this.migration,
shortcuts: this.shortcuts,
};
}

Expand Down

0 comments on commit d513613

Please sign in to comment.