From a566f180c191dbcfbb3a42848968eca9a9faa982 Mon Sep 17 00:00:00 2001 From: Nikolai Sukhanov Date: Fri, 1 Sep 2023 12:16:42 +0400 Subject: [PATCH] feat(controllers): add "ignore input" setting --- .../hub/controller-profile-hub.ts | 10 +++- .../controllers-list-item.component.html | 8 +++ .../controllers-list-item.component.scss | 5 ++ .../control-ignore-input.component.html | 4 ++ .../control-ignore-input.component.scss | 3 + .../control-ignore-input.component.ts | 22 ++++++++ .../control-ignore-input/index.ts | 1 + ...ler-settings-component-resolver.service.ts | 4 +- .../gamepad/gamepad-settings.component.html | 6 +- .../gamepad/gamepad-settings.component.ts | 12 +++- .../hub-controller-settings.component.html | 1 + .../hub-controller-settings.component.scss | 3 + .../hub/hub-controller-settings.component.ts | 55 +++++++++++++++++++ .../settings-renderers/hub/index.ts | 1 + .../keyboards-settings.component.html | 19 ++++--- .../keyboards-settings.component.scss | 1 + .../keyboard/keyboards-settings.component.ts | 7 ++- src/app/store/actions/controllers.actions.ts | 8 +-- .../controller-profile-factory.service.ts | 4 +- .../capture-gamepad-input.effect.ts | 12 ++-- .../capture-hub-button-groups-input.effect.ts | 8 ++- .../capture-hub-green-button-input.effect.ts | 24 ++++++-- .../capture-keyboard-input.effect.ts | 8 +-- .../listen-hub-connect.effect.ts | 1 + .../store/models/controller-settings.model.ts | 3 + src/app/store/provide-store.ts | 2 +- .../reducers/controller-settings.reducer.ts | 3 + src/assets/i18n/en.json | 4 +- 28 files changed, 197 insertions(+), 42 deletions(-) create mode 100644 src/app/controllers/controllers-list/settings-renderers/control-ignore-input/control-ignore-input.component.html create mode 100644 src/app/controllers/controllers-list/settings-renderers/control-ignore-input/control-ignore-input.component.scss create mode 100644 src/app/controllers/controllers-list/settings-renderers/control-ignore-input/control-ignore-input.component.ts create mode 100644 src/app/controllers/controllers-list/settings-renderers/control-ignore-input/index.ts create mode 100644 src/app/controllers/controllers-list/settings-renderers/hub/hub-controller-settings.component.html create mode 100644 src/app/controllers/controllers-list/settings-renderers/hub/hub-controller-settings.component.scss create mode 100644 src/app/controllers/controllers-list/settings-renderers/hub/hub-controller-settings.component.ts create mode 100644 src/app/controllers/controllers-list/settings-renderers/hub/index.ts diff --git a/src/app/controller-profiles/hub/controller-profile-hub.ts b/src/app/controller-profiles/hub/controller-profile-hub.ts index 4ff48be6..3e7756d3 100644 --- a/src/app/controller-profiles/hub/controller-profile-hub.ts +++ b/src/app/controller-profiles/hub/controller-profile-hub.ts @@ -1,12 +1,14 @@ import { Observable, of } from 'rxjs'; import { TranslocoService } from '@ngneat/transloco'; import { ButtonGroupButtonId } from 'rxpoweredup'; +import { ControllerType } from '@app/shared'; import { IControllerProfile } from '../i-controller-profile'; +import { HubControllerSettings } from '../controller-settings'; export const GREEN_BUTTON_INPUT_ID = 'green-button'; -export class ControllerProfileHub implements IControllerProfile { +export class ControllerProfileHub implements IControllerProfile { public readonly axisStateL10nKey: string = ''; public readonly buttonStateL10nKey: string = 'controllerProfiles.buttonState'; @@ -53,7 +55,9 @@ export class ControllerProfileHub implements IControllerProfile { } } - public getDefaultSettings(): null { - return null; + public getDefaultSettings(): HubControllerSettings { + return { + controllerType: ControllerType.Hub, + }; } } diff --git a/src/app/controllers/controllers-list/controllers-list-item/controllers-list-item.component.html b/src/app/controllers/controllers-list/controllers-list-item/controllers-list-item.component.html index 969256cc..ec8b9269 100644 --- a/src/app/controllers/controllers-list/controllers-list-item/controllers-list-item.component.html +++ b/src/app/controllers/controllers-list/controllers-list-item/controllers-list-item.component.html @@ -12,6 +12,14 @@ > {{ controllerName$ | ngrxPush }} + + + {{ 'controller.inputIsIgnored' | transloco }} + diff --git a/src/app/controllers/controllers-list/controllers-list-item/controllers-list-item.component.scss b/src/app/controllers/controllers-list/controllers-list-item/controllers-list-item.component.scss index a2b03f89..73e57697 100644 --- a/src/app/controllers/controllers-list/controllers-list-item/controllers-list-item.component.scss +++ b/src/app/controllers/controllers-list/controllers-list-item/controllers-list-item.component.scss @@ -5,6 +5,11 @@ .controller-panel { width: 100%; + + &__ignore-input-icon { + margin-left: 10px; + color: var(--app-disabled-color); + } } .controller-icon { diff --git a/src/app/controllers/controllers-list/settings-renderers/control-ignore-input/control-ignore-input.component.html b/src/app/controllers/controllers-list/settings-renderers/control-ignore-input/control-ignore-input.component.html new file mode 100644 index 00000000..12b231aa --- /dev/null +++ b/src/app/controllers/controllers-list/settings-renderers/control-ignore-input/control-ignore-input.component.html @@ -0,0 +1,4 @@ + + {{ 'controller.ignoreInputControlTitle' | transloco }} + diff --git a/src/app/controllers/controllers-list/settings-renderers/control-ignore-input/control-ignore-input.component.scss b/src/app/controllers/controllers-list/settings-renderers/control-ignore-input/control-ignore-input.component.scss new file mode 100644 index 00000000..7f26ddcb --- /dev/null +++ b/src/app/controllers/controllers-list/settings-renderers/control-ignore-input/control-ignore-input.component.scss @@ -0,0 +1,3 @@ +:host { + display: block; +} diff --git a/src/app/controllers/controllers-list/settings-renderers/control-ignore-input/control-ignore-input.component.ts b/src/app/controllers/controllers-list/settings-renderers/control-ignore-input/control-ignore-input.component.ts new file mode 100644 index 00000000..dfd60448 --- /dev/null +++ b/src/app/controllers/controllers-list/settings-renderers/control-ignore-input/control-ignore-input.component.ts @@ -0,0 +1,22 @@ +import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; +import { FormControl, ReactiveFormsModule } from '@angular/forms'; +import { MatSlideToggleModule } from '@angular/material/slide-toggle'; +import { NgIf } from '@angular/common'; +import { TranslocoModule } from '@ngneat/transloco'; + +@Component({ + standalone: true, + selector: 'app-control-ignore-input', + templateUrl: './control-ignore-input.component.html', + styleUrls: [ './control-ignore-input.component.scss' ], + imports: [ + MatSlideToggleModule, + ReactiveFormsModule, + NgIf, + TranslocoModule + ], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class ControlIgnoreInputComponent { + @Input() public control?: FormControl; +} diff --git a/src/app/controllers/controllers-list/settings-renderers/control-ignore-input/index.ts b/src/app/controllers/controllers-list/settings-renderers/control-ignore-input/index.ts new file mode 100644 index 00000000..e3aa283d --- /dev/null +++ b/src/app/controllers/controllers-list/settings-renderers/control-ignore-input/index.ts @@ -0,0 +1 @@ +export * from './control-ignore-input.component'; diff --git a/src/app/controllers/controllers-list/settings-renderers/controller-settings-component-resolver.service.ts b/src/app/controllers/controllers-list/settings-renderers/controller-settings-component-resolver.service.ts index 849063bb..afcc1bb1 100644 --- a/src/app/controllers/controllers-list/settings-renderers/controller-settings-component-resolver.service.ts +++ b/src/app/controllers/controllers-list/settings-renderers/controller-settings-component-resolver.service.ts @@ -5,6 +5,7 @@ import { ControllerSettingsModel } from '@app/store'; import { IControllerSettingsRenderer } from './i-controller-settings-renderer'; import { GamepadSettingsComponent } from './gamepad'; import { KeyboardsSettingsComponent } from './keyboard'; +import { HubControllerSettingsComponent } from './hub'; type InferControllerSettings = ControllerSettingsModel & { controllerType: T }; @@ -12,7 +13,8 @@ type InferControllerSettings = ControllerSettingsModel export class ControllerSettingsComponentResolverService { private renderers: { [k in ControllerType]?: Type>> } = { [ControllerType.Keyboard]: KeyboardsSettingsComponent, - [ControllerType.Gamepad]: GamepadSettingsComponent + [ControllerType.Gamepad]: GamepadSettingsComponent, + [ControllerType.Hub]: HubControllerSettingsComponent }; public resolveComponentFor( diff --git a/src/app/controllers/controllers-list/settings-renderers/gamepad/gamepad-settings.component.html b/src/app/controllers/controllers-list/settings-renderers/gamepad/gamepad-settings.component.html index 2d16ef17..eb771d9c 100644 --- a/src/app/controllers/controllers-list/settings-renderers/gamepad/gamepad-settings.component.html +++ b/src/app/controllers/controllers-list/settings-renderers/gamepad/gamepad-settings.component.html @@ -1,6 +1,8 @@ - +
+ +
+

{{ axis.name$ | ngrxPush }}

diff --git a/src/app/controllers/controllers-list/settings-renderers/gamepad/gamepad-settings.component.ts b/src/app/controllers/controllers-list/settings-renderers/gamepad/gamepad-settings.component.ts index 7018f165..80ed06fc 100644 --- a/src/app/controllers/controllers-list/settings-renderers/gamepad/gamepad-settings.component.ts +++ b/src/app/controllers/controllers-list/settings-renderers/gamepad/gamepad-settings.component.ts @@ -23,6 +23,7 @@ import { IControllerSettingsRenderer } from '../i-controller-settings-renderer'; import { GamepadAxisSettings, GamepadSettings, GamepadValueTransformService, IControllerProfile } from '../../../../controller-profiles'; import { InputOutputDiagramComponent } from './input-output-diagram'; import { ActiveZoneHumanReadableValuePipe } from './active-zone-human-readable-value.pipe'; +import { ControlIgnoreInputComponent } from '../control-ignore-input'; type AxisSettingsViewModel = { inputId: string; @@ -36,12 +37,14 @@ type AxisSettingsViewModel = { type ViewModel = { axes: AxisSettingsViewModel[]; + ignoreInputControl: FormControl; }; type GamepadSettingsForm = FormGroup<{ controllerId: FormControl; controllerType: FormControl; axisConfigs: FormGroup<{ [k in string]: ToFormGroup }>; + ignoreInput: FormControl; }>; @Component({ @@ -64,7 +67,8 @@ type GamepadSettingsForm = FormGroup<{ RangeControlComponent, TranslocoModule, ActiveZoneHumanReadableValuePipe, - MatDividerModule + MatDividerModule, + ControlIgnoreInputComponent ], changeDetection: ChangeDetectionStrategy.OnPush }) @@ -114,6 +118,7 @@ export class GamepadSettingsComponent implements IControllerSettingsRenderer(ControllerType.Gamepad, { nonNullable: true }), axisConfigs: this.formBuilder.group<{ [k in string]: ToFormGroup }>({}), + ignoreInput: this.formBuilder.control(settings.ignoreInput, { nonNullable: true }), }); this.canSave$ = this.gamepadSettingsForm.valueChanges.pipe( @@ -132,7 +137,8 @@ export class GamepadSettingsComponent implements IControllerSettingsRenderer profile.getAxisName$(axisId)), ), rawValue$, - outputValue$ + outputValue$, }); } diff --git a/src/app/controllers/controllers-list/settings-renderers/hub/hub-controller-settings.component.html b/src/app/controllers/controllers-list/settings-renderers/hub/hub-controller-settings.component.html new file mode 100644 index 00000000..c487b6b9 --- /dev/null +++ b/src/app/controllers/controllers-list/settings-renderers/hub/hub-controller-settings.component.html @@ -0,0 +1 @@ + diff --git a/src/app/controllers/controllers-list/settings-renderers/hub/hub-controller-settings.component.scss b/src/app/controllers/controllers-list/settings-renderers/hub/hub-controller-settings.component.scss new file mode 100644 index 00000000..7f26ddcb --- /dev/null +++ b/src/app/controllers/controllers-list/settings-renderers/hub/hub-controller-settings.component.scss @@ -0,0 +1,3 @@ +:host { + display: block; +} diff --git a/src/app/controllers/controllers-list/settings-renderers/hub/hub-controller-settings.component.ts b/src/app/controllers/controllers-list/settings-renderers/hub/hub-controller-settings.component.ts new file mode 100644 index 00000000..e99bbede --- /dev/null +++ b/src/app/controllers/controllers-list/settings-renderers/hub/hub-controller-settings.component.ts @@ -0,0 +1,55 @@ +import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { Observable, map } from 'rxjs'; +import { FormBuilder, FormControl } from '@angular/forms'; +import { HubControllerSettingsModel } from '@app/store'; + +import { IControllerSettingsRenderer } from '../i-controller-settings-renderer'; +import { ControlIgnoreInputComponent } from '../control-ignore-input'; + +@Component({ + standalone: true, + selector: 'app-hub-controller-settings', + templateUrl: './hub-controller-settings.component.html', + styleUrls: [ './hub-controller-settings.component.scss' ], + imports: [ + ControlIgnoreInputComponent + ], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class HubControllerSettingsComponent implements IControllerSettingsRenderer { + public readonly canSave$: Observable; + + public readonly ignoreInputControl: FormControl; + + private settings?: HubControllerSettingsModel; + + constructor( + private readonly formBuilder: FormBuilder, + ) { + this.ignoreInputControl = this.formBuilder.control( + false, + { nonNullable: true } + ); + this.canSave$ = this.ignoreInputControl.valueChanges.pipe( + map(() => this.ignoreInputControl.dirty) + ); + } + + public loadSettings( + settings: HubControllerSettingsModel + ): void { + this.settings = settings; + this.ignoreInputControl.setValue(settings.ignoreInput); + } + + public readSettings(): HubControllerSettingsModel | undefined { + if (!this.settings) { + return undefined; + } + return { + ...this.settings, + ignoreInput: this.ignoreInputControl.value + }; + } + +} diff --git a/src/app/controllers/controllers-list/settings-renderers/hub/index.ts b/src/app/controllers/controllers-list/settings-renderers/hub/index.ts new file mode 100644 index 00000000..db258074 --- /dev/null +++ b/src/app/controllers/controllers-list/settings-renderers/hub/index.ts @@ -0,0 +1 @@ +export * from './hub-controller-settings.component'; diff --git a/src/app/controllers/controllers-list/settings-renderers/keyboard/keyboards-settings.component.html b/src/app/controllers/controllers-list/settings-renderers/keyboard/keyboards-settings.component.html index 0e8a295c..460a85b5 100644 --- a/src/app/controllers/controllers-list/settings-renderers/keyboard/keyboards-settings.component.html +++ b/src/app/controllers/controllers-list/settings-renderers/keyboard/keyboards-settings.component.html @@ -1,10 +1,13 @@ -
- - {{ 'controllerProfiles.keyboard.captureNonAlphaNumerics' | transloco }} - - + +
+ +
+
+ + {{ 'controllerProfiles.keyboard.captureNonAlphaNumerics' | transloco }} + + ({{ 'controllerProfiles.keyboard.captureNonAlphaNumericsHint' | transloco }}) -
+
+ diff --git a/src/app/controllers/controllers-list/settings-renderers/keyboard/keyboards-settings.component.scss b/src/app/controllers/controllers-list/settings-renderers/keyboard/keyboards-settings.component.scss index 22d42099..bc94cb4f 100644 --- a/src/app/controllers/controllers-list/settings-renderers/keyboard/keyboards-settings.component.scss +++ b/src/app/controllers/controllers-list/settings-renderers/keyboard/keyboards-settings.component.scss @@ -1,6 +1,7 @@ .keyboard-settings-section { display: flex; flex-direction: column; + margin-bottom: 10px; } .capture-non-alpha-numerics-hint { diff --git a/src/app/controllers/controllers-list/settings-renderers/keyboard/keyboards-settings.component.ts b/src/app/controllers/controllers-list/settings-renderers/keyboard/keyboards-settings.component.ts index 81bafad0..216e9197 100644 --- a/src/app/controllers/controllers-list/settings-renderers/keyboard/keyboards-settings.component.ts +++ b/src/app/controllers/controllers-list/settings-renderers/keyboard/keyboards-settings.component.ts @@ -10,6 +10,7 @@ import { ControllerType, ToFormGroup } from '@app/shared'; import { KeyboardSettingsModel } from '@app/store'; import { IControllerSettingsRenderer } from '../i-controller-settings-renderer'; +import { ControlIgnoreInputComponent } from '../control-ignore-input'; @Component({ standalone: true, @@ -22,7 +23,8 @@ import { IControllerSettingsRenderer } from '../i-controller-settings-renderer'; TranslocoModule, MatIconModule, MatTooltipModule, - NgIf + NgIf, + ControlIgnoreInputComponent ], changeDetection: ChangeDetectionStrategy.OnPush }) @@ -46,7 +48,8 @@ export class KeyboardsSettingsComponent implements IControllerSettingsRenderer, - captureNonAlphaNumerics: this.formBuilder.control(settings.captureNonAlphaNumerics, { nonNullable: true }) + captureNonAlphaNumerics: this.formBuilder.control(settings.captureNonAlphaNumerics, { nonNullable: true }), + ignoreInput: this.formBuilder.control(settings.ignoreInput, { nonNullable: true }) }); this.canSave$ = this.formGroup.valueChanges.pipe( diff --git a/src/app/store/actions/controllers.actions.ts b/src/app/store/actions/controllers.actions.ts index 8dd50ec5..11353294 100644 --- a/src/app/store/actions/controllers.actions.ts +++ b/src/app/store/actions/controllers.actions.ts @@ -1,12 +1,12 @@ import { createActionGroup, emptyProps, props } from '@ngrx/store'; -import { ControllerSettings } from '../../controller-profiles'; +import { GamepadSettings, HubControllerSettings, KeyboardSettings } from '../../controller-profiles'; export const CONTROLLERS_ACTIONS = createActionGroup({ source: 'Controllers', events: { 'wait for connect': emptyProps(), - 'keyboardDiscovered': props<{ profileUid: string; defaultSettings: ControllerSettings }>(), + 'keyboardDiscovered': props<{ profileUid: string; defaultSettings: KeyboardSettings }>(), 'keyboardConnected': props<{ profileUid: string }>(), 'gamepadDiscovered': props<{ id: string; @@ -16,11 +16,11 @@ export const CONTROLLERS_ACTIONS = createActionGroup({ triggerButtonsIndices: number[]; gamepadApiIndex: number; gamepadOfTypeIndex: number; - defaultSettings: ControllerSettings; + defaultSettings: GamepadSettings; }>(), 'gamepadConnected': props<{ id: string; gamepadApiIndex: number; profileUid: string }>(), 'gamepadDisconnected': props<{ id: string }>(), - 'hubDiscovered': props<{ profileUid: string; hubId: string; defaultSettings?: ControllerSettings }>(), + 'hubDiscovered': props<{ profileUid: string; hubId: string; defaultSettings: HubControllerSettings }>(), 'hubConnected': props<{ hubId: string }>(), 'hubDisconnected': props<{ hubId: string }>() } diff --git a/src/app/store/controller-profile-factory.service.ts b/src/app/store/controller-profile-factory.service.ts index 2da59b73..0c46883b 100644 --- a/src/app/store/controller-profile-factory.service.ts +++ b/src/app/store/controller-profile-factory.service.ts @@ -2,7 +2,7 @@ import { Inject, Injectable } from '@angular/core'; import { TranslocoService } from '@ngneat/transloco'; import { Store } from '@ngrx/store'; -import { ControllerSettings, GamepadSettings, IControllerProfile, KeyboardSettings } from '../controller-profiles'; +import { ControllerSettings, GamepadSettings, HubControllerSettings, IControllerProfile, KeyboardSettings } from '../controller-profiles'; import { ControllerProfileKeyboardService } from '../controller-profiles/keyboard'; import { ControllerProfileGenericGamepadFactoryService } from '../controller-profiles/gamepad'; import { GamepadProfile } from '../controller-profiles/gamepad-profile'; @@ -37,7 +37,7 @@ export class ControllerProfileFactoryService { // TODO: refactor, this is a mess public getHubProfile( hubId: string, - ): IControllerProfile { + ): IControllerProfile { const profile = this.hubProfileFactory.build( hubId, ); diff --git a/src/app/store/effects/controllers/capture-input/capture-gamepad-input.effect.ts b/src/app/store/effects/controllers/capture-input/capture-gamepad-input.effect.ts index f00becdf..484acace 100644 --- a/src/app/store/effects/controllers/capture-input/capture-gamepad-input.effect.ts +++ b/src/app/store/effects/controllers/capture-input/capture-gamepad-input.effect.ts @@ -2,7 +2,7 @@ import { concatLatestFrom, createEffect } from '@ngrx/effects'; import { NEVER, Observable, animationFrames, filter, from, map, merge, share, switchMap } from 'rxjs'; import { Action, Store } from '@ngrx/store'; import { inject } from '@angular/core'; -import { APP_CONFIG, ControllerInputType, ControllerType, IAppConfig, WINDOW } from '@app/shared'; +import { ControllerInputType, ControllerType, WINDOW } from '@app/shared'; import { CONTROLLER_CONNECTION_SELECTORS, CONTROLLER_INPUT_SELECTORS } from '../../../selectors'; import { CONTROLLER_INPUT_ACTIONS } from '../../../actions'; @@ -12,13 +12,16 @@ import { GamepadValueTransformService } from '../../../../controller-profiles'; function readGamepads( store: Store, navigator: Navigator, - config: IAppConfig, valueTransformer: GamepadValueTransformService ): Observable { return store.select(CONTROLLER_CONNECTION_SELECTORS.selectGamepadConnections).pipe( switchMap((connectedGamepads) => from(connectedGamepads)), map(({ connection, gamepad, settings }) => { - if (!gamepad || gamepad.controllerType !== ControllerType.Gamepad || !settings || !settings || settings.controllerType !== ControllerType.Gamepad) { + if (!gamepad + || gamepad.controllerType !== ControllerType.Gamepad + || settings?.controllerType !== ControllerType.Gamepad + || settings.ignoreInput + ) { return [ NEVER ]; } const browserGamepad = navigator.getGamepads()[connection.gamepadIndex] as Gamepad; @@ -86,12 +89,11 @@ function createGamepadScheduler(): Observable { export const CAPTURE_GAMEPAD_INPUT = createEffect(( store: Store = inject(Store), window: Window = inject(WINDOW), - config: IAppConfig = inject(APP_CONFIG), valueTransformer: GamepadValueTransformService = inject(GamepadValueTransformService) ) => { return store.select(CONTROLLER_INPUT_SELECTORS.isCapturing).pipe( switchMap((isCapturing) => isCapturing - ? readGamepads(store, window.navigator, config, valueTransformer) + ? readGamepads(store, window.navigator, valueTransformer) : NEVER ) ); diff --git a/src/app/store/effects/controllers/capture-input/capture-hub-button-groups-input.effect.ts b/src/app/store/effects/controllers/capture-input/capture-hub-button-groups-input.effect.ts index 52e5b9bd..2c8248e6 100644 --- a/src/app/store/effects/controllers/capture-input/capture-hub-button-groups-input.effect.ts +++ b/src/app/store/effects/controllers/capture-input/capture-hub-button-groups-input.effect.ts @@ -11,6 +11,7 @@ import { CONTROLLER_INPUT_ACTIONS, CONTROLLER_INPUT_SELECTORS, CONTROLLER_SELECTORS, + CONTROLLER_SETTINGS_SELECTORS, HubStorageService, attachedIoModesIdFn, attachedIoPortModeInfoIdFn, @@ -39,7 +40,8 @@ const SELECT_ATTACHED_IOS_BUTTON_GROUPS_SELECTOR = createSelector( ATTACHED_IO_SELECTORS.selectAll, CONTROLLER_SELECTORS.selectEntities, CONTROLLER_CONNECTION_SELECTORS.selectAll, - (attachedIOModeInfos, attachedIOModes, attachedIOs, controllers, controllerConnections): ListenablePortModeData[] => { + CONTROLLER_SETTINGS_SELECTORS.selectEntities, + (attachedIOModeInfos, attachedIOModes, attachedIOs, controllers, controllerConnections, settings): ListenablePortModeData[] => { const hubControllerConnections = controllerConnections.filter((c) => c.controllerType === ControllerType.Hub); const portModeResult: Map = new Map(); @@ -49,6 +51,10 @@ const SELECT_ATTACHED_IOS_BUTTON_GROUPS_SELECTOR = createSelector( if (!hubController || hubController.controllerType !== ControllerType.Hub) { continue; } + const hubControllerSettings = settings[hubControllerConnection.controllerId]; + if (hubControllerSettings?.ignoreInput) { + continue; + } const hubIos = attachedIOs.filter((io) => io.hubId === hubController.hubId); for (const io of hubIos) { if (portModeResult.has(attachedIosIdFn(io))) { diff --git a/src/app/store/effects/controllers/capture-input/capture-hub-green-button-input.effect.ts b/src/app/store/effects/controllers/capture-input/capture-hub-green-button-input.effect.ts index be7fc52d..a51a4097 100644 --- a/src/app/store/effects/controllers/capture-input/capture-hub-green-button-input.effect.ts +++ b/src/app/store/effects/controllers/capture-input/capture-hub-green-button-input.effect.ts @@ -2,17 +2,31 @@ import { createEffect } from '@ngrx/effects'; import { Action, Store, createSelector } from '@ngrx/store'; import { inject } from '@angular/core'; import { NEVER, Observable, map, mergeAll, mergeMap, switchMap } from 'rxjs'; -import { CONTROLLER_INPUT_ACTIONS, CONTROLLER_INPUT_SELECTORS, HUBS_SELECTORS, HUB_STATS_SELECTORS, HubStorageService, controllerIdFn } from '@app/store'; +import { + CONTROLLER_INPUT_ACTIONS, + CONTROLLER_INPUT_SELECTORS, + CONTROLLER_SETTINGS_SELECTORS, + HUBS_SELECTORS, + HUB_STATS_SELECTORS, + HubStorageService, + controllerIdFn +} from '@app/store'; import { ControllerInputType, ControllerType } from '@app/shared'; import { GREEN_BUTTON_INPUT_ID } from '../../../../controller-profiles/hub'; -const CONNECTED_HUBS_SELECTOR = createSelector( +const HUB_INPUT_READ_SELECTOR = createSelector( HUBS_SELECTORS.selectAll, HUB_STATS_SELECTORS.selectIds, - (hubs, hubStatsIds) => { + CONTROLLER_SETTINGS_SELECTORS.selectEntities, + (hubs, hubStatsIds, settings) => { const hubStatsIdsSet = new Set(hubStatsIds); - return hubs.filter((hub) => hubStatsIdsSet.has(hub.hubId)).map((hub) => hub.hubId); + return hubs.filter((hub) => hubStatsIdsSet.has(hub.hubId)).map((hub) => hub.hubId) + .filter((hub) => { + const hubControllerId = controllerIdFn({ hubId: hub, controllerType: ControllerType.Hub }); + const hubSettings = settings[hubControllerId]; + return !(hubSettings?.ignoreInput); + }); } ); @@ -20,7 +34,7 @@ function readHubsGreenButtons( store: Store, hubStorage: HubStorageService ): Observable { - return store.select(CONNECTED_HUBS_SELECTOR).pipe( + return store.select(HUB_INPUT_READ_SELECTOR).pipe( map((hubIds) => { return hubIds.map((hubId) => { return hubStorage.get(hubId).properties.buttonState.pipe( diff --git a/src/app/store/effects/controllers/capture-input/capture-keyboard-input.effect.ts b/src/app/store/effects/controllers/capture-input/capture-keyboard-input.effect.ts index 3c96055c..f95c49cb 100644 --- a/src/app/store/effects/controllers/capture-input/capture-keyboard-input.effect.ts +++ b/src/app/store/effects/controllers/capture-input/capture-keyboard-input.effect.ts @@ -10,7 +10,7 @@ import { KeyboardSettingsModel, controllerInputIdFn } from '@app/store'; -import { ControllerInputType, WINDOW } from '@app/shared'; +import { ControllerInputType, ControllerType, WINDOW } from '@app/shared'; import { filterKeyboardInput } from '../filter-keyboard-input'; @@ -24,14 +24,14 @@ function readKeyboard( controllerId: string ): Observable { return store.select(CONTROLLER_SETTINGS_SELECTORS.selectByControllerId(controllerId)).pipe( - map((s) => s as KeyboardSettingsModel), + filter((s): s is KeyboardSettingsModel => s?.controllerType === ControllerType.Keyboard && !s.ignoreInput), take(1), mergeMap((settings) => { return fromEvent(window.document, KEY_DOWN_EVENT).pipe( - filterKeyboardInput(settings?.captureNonAlphaNumerics), + filterKeyboardInput(settings.captureNonAlphaNumerics), map((event) => ({ isPressed: true, event })), mergeWith(fromEvent(window.document, KEY_UP_EVENT).pipe( - filterKeyboardInput(settings?.captureNonAlphaNumerics), + filterKeyboardInput(settings.captureNonAlphaNumerics), map((event) => ({ isPressed: false, event })), )), ); diff --git a/src/app/store/effects/controllers/listen-connect/listen-hub-connect.effect.ts b/src/app/store/effects/controllers/listen-connect/listen-hub-connect.effect.ts index 840b12ec..afda83ac 100644 --- a/src/app/store/effects/controllers/listen-connect/listen-hub-connect.effect.ts +++ b/src/app/store/effects/controllers/listen-connect/listen-hub-connect.effect.ts @@ -20,6 +20,7 @@ export const LISTEN_HUB_CONNECT = createEffect(( return CONTROLLERS_ACTIONS.hubDiscovered({ hubId: action.hubId, profileUid: profile.uid, + defaultSettings: profile.getDefaultSettings() }); }) ); diff --git a/src/app/store/models/controller-settings.model.ts b/src/app/store/models/controller-settings.model.ts index 732cb488..1e54cade 100644 --- a/src/app/store/models/controller-settings.model.ts +++ b/src/app/store/models/controller-settings.model.ts @@ -4,15 +4,18 @@ import { GamepadSettings, HubControllerSettings, KeyboardSettings } from '../../ export type KeyboardSettingsModel = { controllerId: string; + ignoreInput: boolean; } & KeyboardSettings; export type GamepadSettingsModel = { controllerId: string; + ignoreInput: boolean; } & GamepadSettings; export type HubControllerSettingsModel = { controllerId: string; controllerType: ControllerType.Hub; + ignoreInput: boolean; } & HubControllerSettings; export type ControllerSettingsModel = KeyboardSettingsModel | GamepadSettingsModel | HubControllerSettingsModel; diff --git a/src/app/store/provide-store.ts b/src/app/store/provide-store.ts index 25062463..d11ca9b2 100644 --- a/src/app/store/provide-store.ts +++ b/src/app/store/provide-store.ts @@ -44,7 +44,7 @@ import { RoutesBuilderService } from '../routing'; import { CONTROLLER_INPUT_ACTIONS, HUB_STATS_ACTIONS } from './actions'; import { HubFacadeService } from './hub-facade.service'; -const STORAGE_VERSION = '18'; +const STORAGE_VERSION = '19'; const REDUCERS: ActionReducerMap = { bluetoothAvailability: BLUETOOTH_AVAILABILITY_FEATURE.reducer, diff --git a/src/app/store/reducers/controller-settings.reducer.ts b/src/app/store/reducers/controller-settings.reducer.ts index a49c2ebe..ae09e18e 100644 --- a/src/app/store/reducers/controller-settings.reducer.ts +++ b/src/app/store/reducers/controller-settings.reducer.ts @@ -27,6 +27,7 @@ export const CONTROLLER_SETTINGS_FEATURE = createFeature({ } const settingsModel: ControllerSettingsModel = { controllerId: action.id, + ignoreInput: false, ...action.defaultSettings }; return CONTROLLER_SETTINGS_ENTITY_ADAPTER.addOne(settingsModel, state); @@ -37,6 +38,7 @@ export const CONTROLLER_SETTINGS_FEATURE = createFeature({ } const settingsModel: ControllerSettingsModel = { controllerId: action.profileUid, + ignoreInput: false, ...action.defaultSettings }; return CONTROLLER_SETTINGS_ENTITY_ADAPTER.addOne(settingsModel, state); @@ -47,6 +49,7 @@ export const CONTROLLER_SETTINGS_FEATURE = createFeature({ } const settingsModel: ControllerSettingsModel = { controllerId: controllerIdFn({ hubId: action.hubId, controllerType: ControllerType.Hub }), + ignoreInput: false, ...action.defaultSettings }; return CONTROLLER_SETTINGS_ENTITY_ADAPTER.addOne(settingsModel, state); diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index 98f51ba5..b7edac00 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -271,7 +271,9 @@ "rawInput": "input", "output": "output", "invert": "Invert", - "save": "Save" + "save": "Save", + "ignoreInputControlTitle": "Ignore input", + "inputIsIgnored": "Input is ignored" }, "controllerProfiles": { "buttonState": "{ value, select, 1 {Pressed} other {Released} }",