1
1
mirror of https://github.com/Fabio286/antares.git synced 2025-02-09 16:28:42 +01:00

feat: delete shortcuts and restore defaults

This commit is contained in:
Fabio Di Stasio 2022-08-10 17:59:59 +02:00
parent 4fc4ddd1d6
commit c22413fde9
17 changed files with 690 additions and 1561 deletions

View File

@ -1,6 +1,7 @@
{
"extends": [
"stylelint-config-standard"
"stylelint-config-standard",
"stylelint-config-recommended-vue"
],
"fix": true,
"formatter": "verbose",
@ -10,6 +11,7 @@
"rules": {
"at-rule-no-unknown": null,
"no-descending-specificity": null,
"font-family-no-missing-generic-family-keyword": null,
"declaration-colon-newline-after": "always-multi-line"
},
"syntax": "scss"

1880
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -181,15 +181,17 @@
"node-loader": "~2.0.0",
"playwright": "~1.21.1",
"playwright-core": "~1.21.1",
"postcss-html": "~1.5.0",
"progress-webpack-plugin": "~1.0.12",
"rimraf": "~3.0.2",
"sass": "~1.42.1",
"sass-loader": "~12.3.0",
"standard-version": "~9.3.1",
"style-loader": "~3.3.1",
"stylelint": "~13.13.1",
"stylelint-config-standard": "~22.0.0",
"stylelint-scss": "~3.21.0",
"stylelint": "~14.9.1",
"stylelint-config-recommended-vue": "~1.4.0",
"stylelint-config-standard": "~26.0.0",
"stylelint-scss": "~4.3.0",
"tree-kill": "~1.2.2",
"ts-loader": "~9.2.8",
"typescript": "~4.6.3",

View File

@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
export default class {
static get _methods () {
return [
@ -180,7 +181,7 @@ export default class {
acc[curr.group] = new Set(curr.types);
return acc;
}, {});
}, {} as any);
const groupsArr = [];
@ -198,12 +199,12 @@ export default class {
});
}
static getGroupsByType (type) {
static getGroupsByType (type: string) {
if (!type) return [];
return this.getGroups().filter(group => group.types.includes(type));
}
static getMethods ({ type, group }) {
static getMethods ({ type, group }: {type: string; group: string}) {
return this._methods.filter(method => method.group === group && method.types.includes(type)).sort((a, b) => {
if (a.name < b.name)
return -1;

View File

@ -1,5 +1,5 @@
export function bufferToBase64 (buf: Buffer) {
const binstr = Array.prototype.map.call(buf, ch => {
const binstr = Array.prototype.map.call(buf, (ch: number) => {
return String.fromCharCode(ch);
}).join('');
return Buffer.from(binstr, 'binary').toString('base64');

View File

@ -1,88 +1,81 @@
export const shortcutEvents: { [key: string]: { l18n: string; l18nParam?: string | number }} = {
'open-new-tab': { l18n: 'message.openNewTab' },
'close-tab': { l18n: 'message.closeTab' },
'next-tab': { l18n: 'message.nextTab' },
'prev-tab': { l18n: 'message.previousTab' },
'open-connections-modal': { l18n: 'message.allConnections' },
'toggle-console': { l18n: 'message.toggleConsole' }
};
interface ShortcutRecord {
event: string;
keys: Electron.Accelerator[];
description?: string;
l18nSlug: string;
l18nParam?: string | number;
/** Needed for default shortcuts */
os: NodeJS.Platform[];
}
/**
* Default shortcuts
*/
const shortcuts: ShortcutRecord[] = [
{
event: 'open-new-tab',
keys: ['CommandOrControl+T'],
description: 'Open a new query tab',
l18nSlug: 'message.openNewTab',
os: ['darwin', 'linux', 'win32']
},
{
event: 'close-tab',
keys: ['CommandOrControl+W'],
description: 'Close tab',
l18nSlug: 'message.closeTab',
os: ['darwin', 'linux', 'win32']
},
{
event: 'next-tab',
keys: ['Alt+CommandOrControl+Right'],
description: 'Next tab',
l18nSlug: 'message.nextTab',
os: ['darwin', 'win32']
},
{
event: 'prev-tab',
keys: ['Alt+CommandOrControl+Left'],
description: 'Previous tab',
l18nSlug: 'message.previousTab',
os: ['darwin', 'win32']
},
{
event: 'next-tab',
keys: ['CommandOrControl+PageDown'],
description: 'Next tab',
l18nSlug: 'message.nextTab',
os: ['linux', 'win32']
},
{
event: 'prev-tab',
keys: ['CommandOrControl+PageUp'],
description: 'Previous tab',
l18nSlug: 'message.previousTab',
os: ['linux', 'win32']
},
{
event: 'open-connections-modal',
keys: ['Shift+CommandOrControl+Space'],
description: 'Show all connections',
l18nSlug: 'message.allConnections',
os: ['darwin', 'linux', 'win32']
},
{
event: 'toggle-console',
keys: ['CommandOrControl+F12'],
description: 'Toggle console',
l18nSlug: 'message.toggleConsole',
os: ['darwin', 'linux', 'win32']
},
{
event: 'toggle-console',
keys: ['CommandOrControl+`'],
description: 'Toggle console',
l18nSlug: 'message.toggleConsole',
os: ['darwin', 'linux', 'win32']
}
];
for (let i = 1; i <= 9; i++) {
shortcuts.push(
{
event: `select-tab-${i}`,
keys: [`CommandOrControl+${i}`],
description: `Select tab number ${i}`,
l18nSlug: 'message.selectTabNumber',
l18nParam: i,
os: ['darwin', 'linux', 'win32']
});
shortcutEvents[`select-tab-${i}`] = {
l18n: 'message.selectTabNumber',
l18nParam: i
};
shortcuts.push({
event: `select-tab-${i}`,
keys: [`CommandOrControl+${i}`],
os: ['darwin', 'linux', 'win32']
});
}
export { shortcuts, ShortcutRecord };

View File

@ -1,4 +1,5 @@
import { app, ipcMain, dialog } from 'electron';
import { app, ipcMain, dialog, BrowserWindow } from 'electron';
import { ShortcutRegister } from '../libs/ShortcutRegister';
export default () => {
ipcMain.on('close-app', () => {
@ -12,4 +13,28 @@ export default () => {
ipcMain.handle('get-download-dir-path', () => {
return app.getPath('downloads');
});
ipcMain.handle('resotre-default-shortcuts', () => {
const mainWindow = BrowserWindow.getAllWindows()[0];
const shortCutRegister = ShortcutRegister.getInstance({ mainWindow });
shortCutRegister.restoreDefaults();
});
ipcMain.handle('reload-shortcuts', () => {
const mainWindow = BrowserWindow.getAllWindows()[0];
const shortCutRegister = ShortcutRegister.getInstance({ mainWindow });
shortCutRegister.reload();
});
ipcMain.handle('update-shortcuts', (event, shortcuts) => {
const mainWindow = BrowserWindow.getAllWindows()[0];
const shortCutRegister = ShortcutRegister.getInstance({ mainWindow });
shortCutRegister.updateShortcuts(shortcuts);
});
ipcMain.handle('unregister-shortcuts', () => {
const mainWindow = BrowserWindow.getAllWindows()[0];
const shortCutRegister = ShortcutRegister.getInstance({ mainWindow });
shortCutRegister.unregister();
});
};

View File

@ -1,6 +1,7 @@
import { BrowserWindow, globalShortcut } from 'electron';
import * as Store from 'electron-store';
import { ShortcutRecord, shortcuts } from 'common/shortcuts';
const shortcutsStore = new Store({ name: 'shortcuts' });
const isDevelopment = process.env.NODE_ENV !== 'production';
const defaultShortcuts = shortcuts.filter(s => s.os.includes(process.platform));
@ -8,12 +9,20 @@ const defaultShortcuts = shortcuts.filter(s => s.os.includes(process.platform));
export class ShortcutRegister {
private _shortcuts: ShortcutRecord[];
private _mainWindow: BrowserWindow;
private static _instance: ShortcutRegister;
constructor (args: { mainWindow: BrowserWindow }) {
private constructor (args: { mainWindow: BrowserWindow }) {
this._mainWindow = args.mainWindow;
this.shortcuts = shortcutsStore.get('shortcuts', defaultShortcuts) as ShortcutRecord[];
}
public static getInstance (args: { mainWindow: BrowserWindow }) {
if (!ShortcutRegister._instance)
ShortcutRegister._instance = new ShortcutRegister(args);
return ShortcutRegister._instance;
}
get shortcuts () {
return this._shortcuts;
}
@ -40,6 +49,8 @@ export class ShortcutRegister {
}
}
}
this._mainWindow.webContents.send('update-shortcuts', this.shortcuts);
}
reload () {

View File

@ -122,7 +122,7 @@ else {
mainWindow = await createMainWindow();
createAppMenu();
shortCutRegister = new ShortcutRegister({ mainWindow });
shortCutRegister = ShortcutRegister.getInstance({ mainWindow });
if (isWindows)
mainWindow.show();

View File

@ -0,0 +1,81 @@
<template>
<div class="form-group has-icon-right p-2 m-0">
<input
class="form-input"
type="text"
:value="pressedKeys"
readonly
:placeholder="t('message.registerAShortcut')"
@focus="isFocus = true"
@blur="isFocus = false"
@keydown.prevent.stop="onKey"
>
<i class="form-icon mdi mdi-keyboard-outline mdi-24px" />
</div>
</template>
<script setup lang="ts">
import { computed, Ref, ref, watch } from 'vue';
import { useI18n } from 'vue-i18n';
import Application from '@/ipc-api/Application';
const { t } = useI18n();
const emit = defineEmits(['update:modelValue']);
const isMacOS = process.platform === 'darwin';
defineProps({
modelValue: String
});
const isFocus = ref(false);
const keyboardEvent: Ref<KeyboardEvent> = ref(null);
const pressedKeys = computed(() => {
const keys: string[] = [];
if (keyboardEvent.value) {
if (keyboardEvent.value.altKey)
keys.push('Alt');
if (keyboardEvent.value.ctrlKey)
keys.push('Control');
if (keyboardEvent.value.metaKey && isMacOS)
keys.push('Meta');
if (keyboardEvent.value.shiftKey)
keys.push('Shift');
if (keyboardEvent.value.code) {
if (!['Control', 'Alt', 'AltGraph', 'Shift', 'Meta', 'CapsLock', 'ContextMenu'].includes(keyboardEvent.value.key))
keys.push(keyboardEvent.value.code.replace('Digit', '').replace('Key', ''));
}
}
return keys.join('+');
});
const onKey = (e: KeyboardEvent) => {
e.stopPropagation();
e.preventDefault();
keyboardEvent.value = e;
};
watch(pressedKeys, () => {
emit('update:modelValue', pressedKeys.value);
});
watch(isFocus, (val) => {
if (val)
Application.unregisterShortcuts();
else
Application.reloadShortcuts();
});
</script>
<style lang="scss" scoped>
.has-icon-right {
.form-input {
padding-right: 1.4rem;
}
.form-icon {
right: 0.8rem;
}
}
</style>

View File

@ -1,10 +1,11 @@
<template>
<div class="p-relative">
<KeyPressDetector />
<div class="shortcuts-tools pb-2 px-2">
<button class="btn btn-dark btn-sm d-flex ml-2">
<i class="mdi mdi-24px mdi-plus mr-1" /><span>{{ t('message.addShortcut') }}</span>
</button>
<button class="btn btn-dark btn-sm d-flex ml-2">
<button class="btn btn-dark btn-sm d-flex ml-2" @click="isConfirmRestoreModal = true">
<i class="mdi mdi-24px mdi-undo mr-1" /><span>{{ t('message.restoreDefaults') }}</span>
</button>
</div>
@ -17,7 +18,7 @@
{{ t('word.event') }}
</div>
</div>
<div class="th no-border" style="width: 100%">
<div class="th no-border" style="width: 100%;">
<div>
{{ t('word.key', 2) }}
</div>
@ -34,7 +35,7 @@
tabindex="0"
>
<div class="td py-1">
{{ t(shortcut.l18nSlug, {param: shortcut.l18nParam}) }}
{{ t(shortcutEvents[shortcut.event].l18n, {param: shortcutEvents[shortcut.event].l18nParam}) }}
</div>
<div
class="td py-1"
@ -42,10 +43,10 @@
v-html="parseKeys(shortcut.keys)"
/>
<div class="td py-1 pr-2">
<button class="shortcut-button btn btn-link btn-sm d-flex p-0 mr-2">
<button class="shortcut-button btn btn-link btn-sm d-flex p-0 px-1 mr-2">
<span>{{ t('word.edit') }}</span><i class="mdi mdi-pencil ml-1" />
</button>
<button class="shortcut-button btn btn-link btn-sm d-flex p-0">
<button class="shortcut-button btn btn-link btn-sm d-flex p-0 px-1" @click="showDeleteModal(shortcut)">
<span>{{ t('word.delete') }}</span><i class="mdi mdi-delete-outline ml-1" />
</button>
</div>
@ -54,16 +55,59 @@
</div>
</div>
</div>
<Teleport to="#window-content">
<ConfirmModal
v-if="isConfirmDeleteModal"
@confirm="deleteShortcut"
@hide="isConfirmDeleteModal = false"
>
<template #header>
<div class="d-flex">
<i class="mdi mdi-24px mdi-delete mr-1" /> {{ t('message.deleteShortcut') }}
</div>
</template>
<template #body>
<div class="mb-2">
{{ t('message.deleteCorfirm') }} <b>{{ t(shortcutEvents[shortcutToDelete.event].l18n, {param: shortcutEvents[shortcutToDelete.event].l18nParam}) }} (<span v-html="parseKeys(shortcutToDelete.keys)" />)</b>?
</div>
</template>
</ConfirmModal>
<ConfirmModal
v-if="isConfirmRestoreModal"
@confirm="restoreDefaults"
@hide="isConfirmRestoreModal = false"
>
<template #header>
<div class="d-flex">
<i class="mdi mdi-24px mdi-undo mr-1" /> {{ t('message.restoreDefaults') }}
</div>
</template>
<template #body>
<div class="mb-2">
{{ t('message.restoreDefaultsQuestion') }}
</div>
</template>
</ConfirmModal>
</Teleport>
</template>
<script setup lang="ts">
import { Ref, ref } from 'vue';
import { storeToRefs } from 'pinia';
import { useI18n } from 'vue-i18n';
import { useSettingsStore } from '@/stores/settings';
import KeyPressDetector from './KeyPressDetector.vue';
import Application from '@/ipc-api/Application';
import { shortcutEvents, ShortcutRecord } from 'common/shortcuts';
import ConfirmModal from '@/components/BaseConfirmModal.vue';
const { t } = useI18n();
const isMacOS = process.platform === 'darwin';
const isConfirmRestoreModal = ref(false);
const isConfirmDeleteModal = ref(false);
const shortcutToDelete: Ref<ShortcutRecord> = ref(null);
const settingsStore = useSettingsStore();
const { shortcuts } = storeToRefs(settingsStore);
@ -77,35 +121,53 @@ const parseKeys = (keys: {[key: number]: string}[]) => {
.replaceAll('CommandOrControl', isMacOS ? 'CMD' : 'CTRL')
).join(', ');
};
const restoreDefaults = () => {
isConfirmRestoreModal.value = false;
return Application.restoreDefaultShortcuts();
};
const showDeleteModal = (shortcut: ShortcutRecord) => {
isConfirmDeleteModal.value = true;
shortcutToDelete.value = shortcut;
};
const deleteShortcut = () => {
const filteredShortcuts = shortcuts.value.filter(s => (
shortcutToDelete.value.event !== s.event && shortcutToDelete.value.keys !== s.keys
));
Application.updateShortcuts(filteredShortcuts);
};
</script>
<style lang="scss" scoped>
.table {
.tr{
.td {
border-right: 3px solid;
border-bottom: 3px solid;
}
&:hover {
.shortcut-button {
opacity: 1;
}
}
.shortcut-button {
font-size: 0.7rem;
height: 1rem;
line-height: 1rem;
display: inline-flex;
align-items: center;
justify-content: center;
opacity: 0;
}
.table {
.tr {
.td {
border-right: 3px solid;
border-bottom: 3px solid;
}
}
.shortcuts-tools{
display: flex;
justify-content: flex-end;
}
&:hover {
.shortcut-button {
opacity: 1;
}
}
.shortcut-button {
font-size: 0.7rem;
height: 1rem;
line-height: 1rem;
display: inline-flex;
align-items: center;
justify-content: center;
opacity: 0;
}
}
}
.shortcuts-tools {
display: flex;
justify-content: flex-end;
}
</style>

View File

@ -305,7 +305,10 @@ export const enUS = {
selectTabNumber: 'Select tab number {param}',
toggleConsole: 'Toggle console',
addShortcut: 'Add shortcut',
restoreDefaults: 'Restore defaults'
restoreDefaults: 'Restore defaults',
restoreDefaultsQuestion: 'Do you confirm to restore default values?',
registerAShortcut: 'Register a shortcut',
deleteShortcut: 'Delete shortcut'
},
faker: {
address: 'Address',

View File

@ -42,6 +42,10 @@ ipcRenderer.on('query-log', (event, logRecord) => {
useConsoleStore().putLog(logRecord);
});
ipcRenderer.on('toggle-console', () => {
useConsoleStore().toggleConsole();
});
// IPC app updates
ipcRenderer.on('checking-for-update', () => {
useApplicationStore().updateStatus = 'checking';
@ -85,3 +89,7 @@ ipcRenderer.on('open-updates-preferences', () => {
useApplicationStore().showSettingModal('update');
ipcRenderer.send('check-for-updates');
});
ipcRenderer.on('update-shortcuts', (event, shortcuts) => {
useSettingsStore().updateShortcuts(shortcuts);
});

View File

@ -1,3 +1,4 @@
import { ShortcutRecord } from 'common/shortcuts';
import { ipcRenderer, OpenDialogOptions, OpenDialogReturnValue } from 'electron';
import { unproxify } from '../libs/unproxify';
@ -9,4 +10,20 @@ export default class {
static getDownloadPathDirectory (): Promise<string> {
return ipcRenderer.invoke('get-download-dir-path');
}
static reloadShortcuts () {
return ipcRenderer.invoke('reload-shortcuts');
}
static updateShortcuts (shortcuts: ShortcutRecord[]) {
return ipcRenderer.invoke('update-shortcuts', unproxify(shortcuts));
}
static restoreDefaultShortcuts () {
return ipcRenderer.invoke('resotre-default-shortcuts');
}
static unregisterShortcuts () {
return ipcRenderer.invoke('unregister-shortcuts');
}
}

View File

@ -1,4 +1,3 @@
import { ipcRenderer } from 'electron';
import { defineStore } from 'pinia';
import { useWorkspacesStore } from './workspaces';
const logsSize = 1000;
@ -57,7 +56,3 @@ export const useConsoleStore = defineStore('console', {
}
}
});
ipcRenderer.on('toggle-console', () => {
useConsoleStore().toggleConsole();
});

View File

@ -2,13 +2,13 @@ import { defineStore } from 'pinia';
import { ipcRenderer } from 'electron';
import { i18n, AvailableLocale } from '@/i18n';
import * as Store from 'electron-store';
import { ShortcutRecord, shortcuts } from 'common/shortcuts';
import { ShortcutRecord } from 'common/shortcuts';
const settingsStore = new Store({ name: 'settings' });
const shortcutsStore = new Store({ name: 'shortcuts' });
const isDarkTheme = window.matchMedia('(prefers-color-scheme: dark)');
const defaultAppTheme = isDarkTheme.matches ? 'dark' : 'light';
const defaultEditorTheme = isDarkTheme.matches ? 'twilight' : 'sqlserver';
const defaultShortcuts = shortcuts.filter(s => s.os.includes(process.platform));
export type EditorFontSize = 'small' | 'medium' | 'large';
export type ApplicationTheme = 'light' | 'dark';
@ -28,7 +28,7 @@ export const useSettingsStore = defineStore('settings', {
restoreTabs: settingsStore.get('restore_tabs', true) as boolean,
disableBlur: settingsStore.get('disable_blur', false) as boolean,
disableScratchpad: settingsStore.get('disable_scratchpad', false) as boolean,
shortcuts: shortcutsStore.get('shortcuts', defaultShortcuts) as ShortcutRecord[]
shortcuts: shortcutsStore.get('shortcuts', []) as ShortcutRecord[]
}),
actions: {
changeLocale (locale: AvailableLocale) {
@ -84,6 +84,9 @@ export const useSettingsStore = defineStore('settings', {
changeDisableScratchpad (val: boolean) {
this.disableScratchpad = val;
settingsStore.set('disable_scratchpad', this.disableScratchpad);
},
updateShortcuts (shortcuts: ShortcutRecord[]) {
this.shortcuts = shortcuts;
}
}
});

View File

@ -3,8 +3,8 @@
"./tests/**/*",
"./src/main/**/*",
"./src/renderer/**/*",
"./src/common/interfaces/antares.ts"
, "src/common/libs/jsonToSql.ts" ],
"./src/common/**/*",
],
"exclude": ["./src/renderer/libs/ext-language_tools.js"],
"compilerOptions": {
"baseUrl": "./",