mirror of
https://github.com/Eugeny/tabby
synced 2024-12-12 22:32:57 +00:00
Mark duplicate hotkeys
This commit is contained in:
parent
bc243a2741
commit
72bc58332d
7 changed files with 77 additions and 28 deletions
|
@ -3,6 +3,11 @@ export interface HotkeyDescription {
|
|||
name: string
|
||||
}
|
||||
|
||||
export interface Hotkey {
|
||||
strokes: string[] | string; // may be a sequence of strokes
|
||||
isDuplicate: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extend to provide your own hotkeys. A corresponding [[ConfigProvider]]
|
||||
* must also provide the `hotkeys.foo` config options with the default values
|
||||
|
|
|
@ -256,6 +256,11 @@ multi-hotkey-input {
|
|||
}
|
||||
}
|
||||
|
||||
.item:has(.duplicate) {
|
||||
background-color: theme-color('danger');
|
||||
border: 1px solid theme-color('danger');
|
||||
}
|
||||
|
||||
.add {
|
||||
color: #777;
|
||||
padding: 4px 10px 0;
|
||||
|
@ -265,6 +270,11 @@ multi-hotkey-input {
|
|||
&:hover { background: darken($body-bg2, 5%); }
|
||||
&:active { background: darken($body-bg2, 15%); }
|
||||
}
|
||||
|
||||
.add:has(.duplicate), .item:has(.duplicate) .body, .item:has(.duplicate) .remove {
|
||||
&:hover { background: darken(theme-color('danger'), 5%); }
|
||||
&:active { background: darken(theme-color('danger'), 15%); }
|
||||
}
|
||||
}
|
||||
|
||||
hotkey-input-modal {
|
||||
|
|
|
@ -162,6 +162,11 @@ multi-hotkey-input {
|
|||
}
|
||||
}
|
||||
|
||||
.item:has(.duplicate) {
|
||||
background-color: theme-color('danger');
|
||||
border: 1px solid theme-color('danger');
|
||||
}
|
||||
|
||||
.add {
|
||||
color: #777;
|
||||
padding: 4px 10px 0;
|
||||
|
@ -171,6 +176,11 @@ multi-hotkey-input {
|
|||
&:hover { background: darken($body-bg2, 5%); }
|
||||
&:active { background: darken($body-bg2, 15%); }
|
||||
}
|
||||
|
||||
.add:has(.duplicate), .item:has(.duplicate) .body, .item:has(.duplicate) .remove {
|
||||
&:hover { background: darken(theme-color('danger'), 5%); }
|
||||
&:active { background: darken(theme-color('danger'), 15%); }
|
||||
}
|
||||
}
|
||||
|
||||
hotkey-input-modal {
|
||||
|
|
|
@ -14,6 +14,6 @@ h3.mb-3(translate) Hotkeys
|
|||
span.ml-2.text-muted ({{hotkey.id}})
|
||||
.col-4.pr-5
|
||||
multi-hotkey-input(
|
||||
[model]='getHotkey(hotkey.id) || []',
|
||||
(modelChange)='setHotkey(hotkey.id, $event)'
|
||||
[hotkeys]='getHotkeys(hotkey.id) || []',
|
||||
(hotkeysChange)='setHotkeys(hotkey.id, $event)'
|
||||
)
|
||||
|
|
|
@ -7,6 +7,7 @@ import {
|
|||
HotkeysService,
|
||||
HostAppService,
|
||||
} from 'tabby-core'
|
||||
import { Hotkey } from 'tabby-core/src/api/hotkeyProvider'
|
||||
|
||||
_('Search hotkeys')
|
||||
|
||||
|
@ -30,28 +31,44 @@ export class HotkeySettingsTabComponent {
|
|||
})
|
||||
}
|
||||
|
||||
getHotkey (id: string) {
|
||||
getHotkeys (id: string): Hotkey[] {
|
||||
let ptr = this.config.store.hotkeys
|
||||
for (const token of id.split(/\./g)) {
|
||||
ptr = ptr[token]
|
||||
}
|
||||
return ptr
|
||||
return (ptr || []).map(hotkey => this.detectDuplicates(hotkey))
|
||||
}
|
||||
|
||||
setHotkey (id: string, value) {
|
||||
setHotkeys (id: string, hotkeys: Hotkey[]) {
|
||||
let ptr = this.config.store
|
||||
let prop = 'hotkeys'
|
||||
for (const token of id.split(/\./g)) {
|
||||
ptr = ptr[prop]
|
||||
prop = token
|
||||
}
|
||||
ptr[prop] = value
|
||||
ptr[prop] = hotkeys.map(hotkey =>
|
||||
hotkey.strokes.length === 1 && Array.isArray(hotkey.strokes)
|
||||
? hotkey.strokes[0]
|
||||
: hotkey.strokes,
|
||||
)
|
||||
this.config.save()
|
||||
}
|
||||
|
||||
hotkeyFilterFn (hotkey: HotkeyDescription, query: string): boolean {
|
||||
// eslint-disable-next-line @typescript-eslint/restrict-plus-operands
|
||||
const s = hotkey.name + hotkey.id + (this.getHotkey(hotkey.id) || []).toString()
|
||||
const s = hotkey.name + hotkey.id + this.getHotkeys(hotkey.id).map(h => h.strokes).toString()
|
||||
return s.toLowerCase().includes(query.toLowerCase())
|
||||
}
|
||||
|
||||
private detectDuplicates (strokes: string[] | string): Hotkey {
|
||||
const allHotkeys = Object
|
||||
.values(this.config.store.hotkeys)
|
||||
.filter((value: unknown) => Array.isArray(value))
|
||||
.flat()
|
||||
|
||||
const isDuplicate = allHotkeys
|
||||
.filter(hotkey => JSON.stringify(hotkey) === JSON.stringify(strokes))
|
||||
.length > 1
|
||||
|
||||
return { strokes, isDuplicate }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
.item(*ngFor='let item of model')
|
||||
.body((click)='editItem(item)')
|
||||
.stroke(*ngFor='let stroke of item') {{stroke}}
|
||||
.remove((click)='removeItem(item)') ×
|
||||
.item(*ngFor='let hotkey of hotkeys')
|
||||
.body((click)='editItem(hotkey)')
|
||||
.stroke(*ngFor='let stroke of hotkey.strokes')
|
||||
span(*ngIf='!hotkey.isDuplicate', translate) {{stroke}}
|
||||
span.duplicate(*ngIf='hotkey.isDuplicate', translate) {{stroke}}
|
||||
.remove((click)='removeItem(hotkey)') ×
|
||||
|
||||
.add((click)='addItem()', translate) Add...
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { Component, Input, Output, EventEmitter, ChangeDetectionStrategy } from '@angular/core'
|
||||
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
|
||||
import { HotkeyInputModalComponent } from './hotkeyInputModal.component'
|
||||
import { Hotkey } from 'tabby-core/src/api/hotkeyProvider'
|
||||
|
||||
/** @hidden */
|
||||
@Component({
|
||||
|
@ -10,37 +11,41 @@ import { HotkeyInputModalComponent } from './hotkeyInputModal.component'
|
|||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class MultiHotkeyInputComponent {
|
||||
@Input() model: string[][] = []
|
||||
@Output() modelChange = new EventEmitter()
|
||||
@Input() hotkeys: Hotkey[] = []
|
||||
@Output() hotkeysChange = new EventEmitter()
|
||||
|
||||
constructor (
|
||||
private ngbModal: NgbModal,
|
||||
) { }
|
||||
|
||||
ngOnChanges (): void {
|
||||
if (typeof this.model === 'string') {
|
||||
this.model = [this.model]
|
||||
}
|
||||
this.model = this.model.map(item => typeof item === 'string' ? [item] : item)
|
||||
this.hotkeys = this.hotkeys.map(hotkey => typeof hotkey.strokes === 'string' ? { ...hotkey, strokes: [hotkey.strokes] } : hotkey)
|
||||
}
|
||||
|
||||
editItem (item: string[]): void {
|
||||
this.ngbModal.open(HotkeyInputModalComponent).result.then((value: string[]) => {
|
||||
this.model[this.model.findIndex(x => x === item)] = value
|
||||
this.model = this.model.slice()
|
||||
this.modelChange.emit(this.model)
|
||||
editItem (item: Hotkey): void {
|
||||
this.ngbModal.open(HotkeyInputModalComponent).result.then((newStrokes: string[]) => {
|
||||
this.hotkeys.find(hotkey => this.isEqual(hotkey, item))!.strokes = newStrokes
|
||||
this.storeUpdatedHotkeys()
|
||||
})
|
||||
}
|
||||
|
||||
addItem (): void {
|
||||
this.ngbModal.open(HotkeyInputModalComponent).result.then((value: string[]) => {
|
||||
this.model = this.model.concat([value])
|
||||
this.modelChange.emit(this.model)
|
||||
this.hotkeys.push({ strokes: value, isDuplicate: false })
|
||||
this.storeUpdatedHotkeys()
|
||||
})
|
||||
}
|
||||
|
||||
removeItem (item: string[]): void {
|
||||
this.model = this.model.filter(x => x !== item)
|
||||
this.modelChange.emit(this.model)
|
||||
removeItem (item: Hotkey): void {
|
||||
this.hotkeys = this.hotkeys.filter(x => x !== item)
|
||||
this.storeUpdatedHotkeys()
|
||||
}
|
||||
|
||||
private storeUpdatedHotkeys () {
|
||||
this.hotkeysChange.emit(this.hotkeys)
|
||||
}
|
||||
|
||||
private isEqual (h: Hotkey, item: Hotkey) {
|
||||
return JSON.stringify(h.strokes) === JSON.stringify(item.strokes)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue