Kasper
Kasper

Reputation: 13592

How do I make a Stream of KeyboardEvent's that is triggered on long pressing the key ? (Dart)

How would I create a Stream of KeyBoardEvent's that is triggered when long pressing the key in some html element.

Similarly, I'm also interested in an Angular2 directive (longpress) (with the same idea).

Upvotes: 1

Views: 660

Answers (2)

Naveed Ahmed
Naveed Ahmed

Reputation: 10386

Below is the typescript version,if anyone is interested:

import { Directive, EventEmitter, Output, Input, HostListener } from '@angular/core';

    @Directive({
        selector: '[longpress]'
    })
    export class LongPressDirective {

      @Output() longpress: EventEmitter<KeyboardEvent> = new EventEmitter(true);

      _startEvent: KeyboardEvent;
      @Input() longpressDelay: number = 1000;

      timer: any;

      @HostListener('keydown', ['$event'])
      @HostListener('keyup', ['$event'])
      keyEventHandler(event: KeyboardEvent) {
        if (this._startEvent == null ||
          this._startEvent.type != event.type ||
          this._startEvent.keyCode != event.keyCode) {

          //console.log(event.type, event);
          if (this.timer != null) {
            clearTimeout(this.timer);
          }

          this._startEvent = event;

          if(event.type == 'keydown') {
            this.timer = setTimeout(() => {
              console.log('longpress');
              this.longpress.emit(this._startEvent);
              clearTimeout(this.timer);
              this.timer = null;
            }, this.longpressDelay);
          }
        }
      }
    }

Upvotes: 1

G&#252;nter Z&#246;chbauer
G&#252;nter Z&#246;chbauer

Reputation: 657348

@Directive(
    selector: '[longpress]')
class LongPress {
  @Output() EventEmitter<KeyboardEvent> longpress =
      new EventEmitter<KeyboardEvent>();

  KeyboardEvent _startEvent;
  @Input() Duration longpressDelay = new Duration(seconds: 2);
  Timer timer;

  @HostListener("keydown", const [r"$event"])
  @HostListener("keyup", const [r"$event"])
  void keyEventHandler(KeyboardEvent event) {
    if (_startEvent == null ||
        _startEvent.type != event.type ||
        _startEvent.keyCode != event.keyCode) {
      if (timer != null) {
        timer.cancel();
      }
      _startEvent = event;

      if(event.type == 'keyup') {
        timer = new Timer(longpressDelay, () {
          longpress.add(_startEvent);
          timer = null;
        });
      }
    }
  }
}

and use it like

<label for="input">Longpress: </label><input id="longpress" longpress (longpress)="longPressed($event)">

I have yet to figure out to make the directive selector work with (...) so this works as well:

<label for="input">Longpress: </label><input id="longpress" (longpress)="longPressed($event)">

Event handling (preventDefault) doesn't seem to work properly yet. Adding this directive to an <input> breaks writing in the input.

A workaround is to subscribe to keydown/keyup this way instead

LongPress(ElementRef elementRef) {
  (elementRef.nativeElement as Element).onKeyDown.listen(keyEventHandler);
  (elementRef.nativeElement as Element).onKeyUp.listen(keyEventHandler);
}

Upvotes: 1

Related Questions