diff --git a/package-lock.json b/package-lock.json index 8439a381..fef96fda 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "sengi", - "version": "0.15.0", + "version": "0.16.2", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -857,6 +857,11 @@ "@types/jasmine": "*" } }, + "@types/mousetrap": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/@types/mousetrap/-/mousetrap-1.6.3.tgz", + "integrity": "sha512-13gmo3M2qVvjQrWNseqM3+cR6S2Ss3grbR2NZltgMq94wOwqJYQdgn8qzwDshzgXqMlSUtyPZjysImmktu22ew==" + }, "@types/node": { "version": "8.9.5", "resolved": "https://registry.npmjs.org/@types/node/-/node-8.9.5.tgz", @@ -1189,6 +1194,15 @@ "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", "dev": true }, + "angular2-hotkeys": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/angular2-hotkeys/-/angular2-hotkeys-2.1.5.tgz", + "integrity": "sha512-HiAnK1pW7lns5LpxtRsdkRRb5iVa7fv8Cf69Jye6l9gI6/IyvaVDptRtsWmdIG7VAr2Ngz6Yeehkym39O/LdgA==", + "requires": { + "@types/mousetrap": "^1.6.0", + "mousetrap": "^1.6.0" + } + }, "ansi-align": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz", @@ -8105,6 +8119,11 @@ } } }, + "mousetrap": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/mousetrap/-/mousetrap-1.6.3.tgz", + "integrity": "sha512-bd+nzwhhs9ifsUrC2tWaSgm24/oo2c83zaRyZQF06hYA6sANfsXHtnZ19AbbbDXCDzeH5nZBSQ4NvCjgD62tJA==" + }, "move-concurrently": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", diff --git a/package.json b/package.json index c29f7c61..d0f72535 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,7 @@ "@fortawesome/free-solid-svg-icons": "^5.7.0", "@ngxs/storage-plugin": "^3.2.0", "@ngxs/store": "^3.2.0", + "angular2-hotkeys": "^2.1.5", "bootstrap": "^4.1.3", "core-js": "^2.5.4", "emojione": "~4.5.0", diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 8dc37fc0..24f67ffe 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -16,6 +16,7 @@ import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'; import { ContextMenuModule } from 'ngx-contextmenu'; import { PickerModule } from '@ctrl/ngx-emoji-mart'; import { OwlDateTimeModule, OwlNativeDateTimeModule } from 'ng-pick-datetime'; +import { HotkeyModule } from 'angular2-hotkeys'; import { AppComponent } from "./app.component"; import { LeftSideBarComponent } from "./components/left-side-bar/left-side-bar.component"; @@ -159,7 +160,8 @@ const routes: Routes = [ SettingsState ]), NgxsStoragePluginModule.forRoot(), - ContextMenuModule.forRoot() + ContextMenuModule.forRoot(), + HotkeyModule.forRoot() ], providers: [AuthService, NavigationService, NotificationService, MastodonService, StreamingService], bootstrap: [AppComponent], diff --git a/src/app/components/streams-selection-footer/streams-selection-footer.component.html b/src/app/components/streams-selection-footer/streams-selection-footer.component.html index f354adc6..bf3678a0 100644 --- a/src/app/components/streams-selection-footer/streams-selection-footer.component.html +++ b/src/app/components/streams-selection-footer/streams-selection-footer.component.html @@ -1,5 +1,7 @@ \ No newline at end of file diff --git a/src/app/components/streams-selection-footer/streams-selection-footer.component.ts b/src/app/components/streams-selection-footer/streams-selection-footer.component.ts index f0fd16b7..944fe9d7 100644 --- a/src/app/components/streams-selection-footer/streams-selection-footer.component.ts +++ b/src/app/components/streams-selection-footer/streams-selection-footer.component.ts @@ -1,7 +1,9 @@ import { Component, OnInit } from '@angular/core'; import { Observable } from 'rxjs'; -import { StreamElement, StreamTypeEnum } from '../../states/streams.state'; import { Store } from '@ngxs/store'; +import { HotkeysService, Hotkey } from 'angular2-hotkeys'; + +import { StreamElement, StreamTypeEnum } from '../../states/streams.state'; import { NavigationService } from '../../services/navigation.service'; @Component({ @@ -14,9 +16,20 @@ export class StreamsSelectionFooterComponent implements OnInit { private streams$: Observable; constructor( + private readonly hotkeysService: HotkeysService, private readonly navigationService: NavigationService, private readonly store: Store) { this.streams$ = this.store.select(state => state.streamsstatemodel.streams); + + this.hotkeysService.add(new Hotkey('ctrl+right', (event: KeyboardEvent): boolean => { + this.nextColumnSelected(); + return false; + })); + + this.hotkeysService.add(new Hotkey('ctrl+left', (event: KeyboardEvent): boolean => { + this.previousColumnSelected(); + return false; + })); } ngOnInit() { @@ -25,9 +38,36 @@ export class StreamsSelectionFooterComponent implements OnInit { }); } + private nextColumnSelected() { + const nbStreams = this.streams.length; + const selectedElement = this.streams.find(x => x.isSelected); + let currentSelectionIndex = 0; + if (selectedElement) { + currentSelectionIndex = this.streams.indexOf(selectedElement); + } + + if(currentSelectionIndex < nbStreams - 1){ + this.onColumnSelection(currentSelectionIndex + 1); + } + } + + private previousColumnSelected() { + const selectedElement = this.streams.find(x => x.isSelected); + let currentSelectionIndex = 0; + if (selectedElement) { + currentSelectionIndex = this.streams.indexOf(selectedElement); + } + + if(currentSelectionIndex > 0){ + this.onColumnSelection(currentSelectionIndex - 1); + } else { + this.onColumnSelection(0); + } + } + onColumnSelection(index: number): boolean { this.streams.forEach(x => x.isSelected = false); - + const selectedStream = this.streams[index]; selectedStream.isSelected = true; @@ -59,7 +99,7 @@ export class StreamsSelectionFooterComponent implements OnInit { } class SelectableStream { - constructor(public readonly stream: StreamElement){ + constructor(public readonly stream: StreamElement) { } isSelected: boolean;