Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

182
Vistas
Resume video if user is inactive/idle for 30 seconds (RxJs)

Let me explain functionality a bit. My goal is when the video is playing if a user clicks on the video it will be paused then he might do something along the way. In the meantime I need to detect if a user is idle for 30 sec. If so then automatically resume the video again.

I have implemented using the javascript basic setTimeout functionality. Let me share the code below

@HostListener('window:click', ['$event'])
onClick: (event) => {
    // stop the video
    this.activity = setTimeout(() => { /* resume */ } , 30000)
}


@HostListener('window:mousemove', ['$event'])
onMouseMove: (event) => {
    clearTimeout(this.activity)
    this.activity = setTimeout(() => { /* resume */ } , 30000)
}

Any suggestion how this can be solved using the RxJs way?

about 4 years ago · Juan Pablo Isaza
2 Respuestas
Responde la pregunta

0

activity = new Subject<void>();

@HostListener('window:click', ['$event'])
onClick(event: any) {
    // stop the video
    interval(30000).pipe(takeUntil(this.activity)).subscribe(() => {
        /* resume */
        this.activity.next();
        this.activity.complete();
    });
}


@HostListener('window:mousemove', ['$event'])
onMouseMove(event: any) {
    this.activity.next();
    this.activity.complete();

    this.activity = new Subject<void>();

    interval(30000).pipe(takeUntil(this.activity)).subscribe(() => {
        /* resume */
        this.activity.next();
        this.activity.complete();
    });
}
about 4 years ago · Juan Pablo Isaza Denunciar

0

This is what I came up with:

It runs outside the Angular Zone. Won't burden your app with change detection when the mouse is moving. It triggers change detection only when the video is stopped or continued.

import { DOCUMENT } from '@angular/common';
import { Inject, Injectable, NgZone } from '@angular/core';
import {
  BehaviorSubject,
  fromEvent,
  merge,
  Observable,
  of,
  Subject,
} from 'rxjs';
import {
  distinctUntilChanged,
  mapTo,
  startWith,
  switchMapTo,
  debounceTime,
  takeUntil,
} from 'rxjs/operators';

@Injectable({ providedIn: 'root' })
export class VideoService {
  private readonly onDestroy = new Subject<void>();
  readonly isPlaying$: Observable<boolean> = new BehaviorSubject(true);

  constructor(
    @Inject(DOCUMENT) private readonly document: Document,
    private readonly ngZone: NgZone
  ) {
    // Run the whole logic outside of angular, so it won't burdent the app
    this.ngZone.runOutsideAngular(() => {
      fromEvent(this.document, 'click', { passive: true })
        .pipe(
          // On every click we create a merge observable, and unsubscribe from the previous one if exists
          switchMapTo(
            // We merge two observables
            merge(
              // one that sets the playing to false instantly
              of(false),
              // Subscribe to the documents mousemove
              fromEvent(this.document, 'mousemove', { passive: true }).pipe(
                // we start the stream with a value, so after the clicking it will go back to playing without moving the cursor.
                startWith(null),
                // With debounceTime we wait for no mousemove
                debounceTime(1000),
                // All values are mapped to true
                mapTo(true)
              )
            )
          ),
          distinctUntilChanged(),
          takeUntil(this.onDestroy)
        )
        .subscribe((value) =>
          // when we get a different value run it in the zone, so Angular will know to run change detection.
          this.ngZone.run(() => {
            (this.isPlaying$ as BehaviorSubject<boolean>).next(value);
          })
        );
    });
  }

  ngOnDestroy() {
    this.onDestroy.next();
    this.onDestroy.complete();
  }
}

Running example

I'm interested in other solutions, as mine does not seems to be simple. I feel it can be done simpler too.

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda