{"version":3,"file":"io-player.mjs","sources":["../../src/app/io-player/io-player/io-player.service.ts","../../src/app/io-player/io-player/io-player.component.ts","../../src/app/io-player/io-player/io-player.component.html","../../src/app/io-player/io-player.module.ts","../../src/io-player.ts"],"sourcesContent":["import {Injectable, OnDestroy} from '@angular/core';\nimport {BehaviorSubject, from, fromEvent, Observable, Subscription} from 'rxjs';\nimport {map} from 'rxjs/operators';\n\n\n@Injectable()\nexport class IoPlayerService implements OnDestroy {\n\n    private _audio: HTMLAudioElement;\n    private _isPlaying = false;\n    private _isPlaying$: BehaviorSubject<boolean>;\n    private subscriptions: Subscription[] = [];\n\n    constructor() {\n        this._isPlaying$ = new BehaviorSubject(this._isPlaying);\n    }\n\n\n    ngOnDestroy() {\n        if (this._isPlaying) {\n            this.pause();\n        }\n        this.subscriptions.forEach(subscription => subscription.unsubscribe());\n    }\n\n    /**\n     * @description initiatize audio player.\n     */\n    init(source: string) {\n        this._audio = document.createElement('audio');\n        this._audio.src = source;\n        this.audioFinish$.subscribe(() => this.pause());\n    }\n\n    /**\n     * @description API to play current player.\n     */\n    play() {\n        if (!this._isPlaying) {\n            from(this._audio.play()).subscribe(() => {\n                this.toggleIsPlaying();\n            });\n        }\n    }\n\n    /**\n     * @description API to pause player.\n     */\n    pause() {\n      if (!this._isPlaying) return;\n      this._audio.pause();\n      this.toggleIsPlaying();\n    }\n\n    forward(offset = 10.0) {\n      if (!this._isPlaying) return;\n      this._audio.currentTime += offset;\n    }\n\n    backward(offset = 10.0) {\n      if (!this._isPlaying) return;\n      this._audio.currentTime -= offset;\n    }\n\n    /**\n     * @description ask for specific pourcentage position.\n     */\n    readFromPercentage(percentage: number) {\n        this._audio.currentTime = this._audio.duration * percentage / 100;\n    }\n\n    /**\n     * @description switch isPlaying state.\n     */\n    private toggleIsPlaying() {\n        this._isPlaying = !this._isPlaying;\n        this._isPlaying$.next(this._isPlaying);\n    }\n\n    /**\n     * @description observable of current percentage position in audio.\n     */\n    get percentageReaded$(): Observable<number> {\n        return fromEvent(this._audio, 'timeupdate').pipe(map(() => {\n            return (this._audio.currentTime / this._audio.duration) * 100;\n        }));\n    }\n\n    /**\n     * @description observable who notify when 'ended' audio event is fire.\n     */\n    get audioFinish$(): Observable<void> {\n        return fromEvent(this._audio, 'ended').pipe(map(() => {\n            return null;\n        }));\n    }\n\n    /**\n     * @description Observable to determine if current sound is playing or not.\n     */\n    get isPlaying$(): Observable<boolean> {\n        return this._isPlaying$.asObservable();\n    }\n}\n","import {\n    ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, EventEmitter, Input, OnDestroy, OnInit, Output,\n    ViewChild\n} from '@angular/core';\nimport {Subscription} from 'rxjs/internal/Subscription';\nimport {IoPlayerService} from './io-player.service';\n\n@Component({\n  selector: 'io-player',\n  templateUrl: './io-player.component.html',\n  styleUrls: ['./io-player.component.scss'],\n  providers: [IoPlayerService],\n  changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class IoPlayerComponent implements OnInit, OnDestroy {\n  @Input() src: string;\n  @Input() cover: string;\n  @Input() author: string;\n  @Input() song: string;\n\n  @Input() set fastForward(step:string) {\n    this.forwardOffsetStep = parseFloat(step);\n  }\n\n  // eslint-disable-next-line  @angular-eslint/no-output-rename\n  @Output('progression') progression$: EventEmitter<number>;\n\n  @ViewChild('coverEl') coverElement: ElementRef;\n  @ViewChild('timelineBar') timelineElement: ElementRef;\n\n  public isPlaying = false;\n  public progression = 0;\n  public forwardOffsetStep: number = 10.0;\n  private subscriptions: Subscription[] = [];\n\n  constructor(\n      public playerService: IoPlayerService,\n      private changeRef: ChangeDetectorRef\n  ) {\n    this.progression$ = new EventEmitter<number>();\n  }\n\n  ngOnInit() {\n    this.playerService.init(this.src);\n    this.subscriptions.push(\n        this.playerService.isPlaying$.subscribe(state => {\n            this.isPlaying = state;\n            this.changeRef.detectChanges();\n        }),\n        this.playerService.percentageReaded$.subscribe(state => {\n          this.progression = state;\n          this.progression$.emit(state);\n          this.changeRef.detectChanges();\n        })\n    );\n  }\n\n  ngOnDestroy() {\n    this.subscriptions.forEach(subscription => subscription.unsubscribe());\n  }\n\n  /**\n   * Click handler on play pause button.\n   */\n  onPlayHandler() {\n    if (!this.isPlaying) {\n      this.playerService.play();\n    } else {\n      this.playerService.pause();\n    }\n  }\n\n  /**\n   * Click Handler on timeline bar\n   */\n  onChangeTimelinekHandler($event: MouseEvent) {\n      const percentage = Math.floor(($event.offsetX / this.timelineElement.nativeElement.offsetWidth) * 100);\n      this.playerService.readFromPercentage(percentage);\n  }\n\n  onFastBackwardHandler() {\n    this.playerService.backward(this.forwardOffsetStep);\n  }\n  onFastForwardHandler() {\n    this.playerService.forward(this.forwardOffsetStep);\n  }\n}\n","<div class=\"player\" [ngClass]=\"{play: isPlaying}\">\n  <div class=\"player__bar\">\n    <div class=\"player__album\">\n      <div class=\"player__scale-wrapper\" [ngClass]=\"{'isPlaying': isPlaying}\">\n        <div class=\"player__albumImg active-song\" #coverEl [ngStyle]=\"{backgroundImage: 'url('+cover+')'}\">\n        </div>\n      </div>\n    </div>\n    <div class=\"player__controls\">\n      <div class=\"player__prev\" (click)=\"onFastBackwardHandler()\">\n        <svg class=\"icon\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 100 100\"><path d=\"M26.695 34.434v31.132L54.5 49.998z\"/><path d=\"M24.07 34.434v31.132c0 2.018 2.222 3.234 3.95 2.267l27.804-15.568c1.706-.955 1.707-3.578 0-4.533L28.02 32.168c-2.957-1.655-5.604 2.88-2.649 4.533l27.805 15.564v-4.533L25.371 63.3l3.95 2.267V34.435c-.001-3.387-5.251-3.387-5.251-.001z\"/><g><path d=\"M55.5 34.434v31.132l27.805-15.568z\"/><path d=\"M52.875 34.434v31.132c0 2.018 2.222 3.234 3.949 2.267 9.27-5.189 18.537-10.379 27.805-15.568 1.705-.955 1.705-3.578 0-4.533L56.824 32.168c-2.957-1.655-5.604 2.88-2.648 4.533l27.803 15.564v-4.533L54.176 63.3l3.949 2.267V34.435c0-3.387-5.25-3.387-5.25-.001z\"/></g></svg>\n      </div>\n\n      <div class=\"player__play\" (click)=\"onPlayHandler()\">\n        <svg class=\"icon play\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 64 64\"><path d=\"M51.109 30.335l-36-24A2 2 0 0 0 12 8v48a2.003 2.003 0 0 0 2 2c.388 0 .775-.113 1.109-.336l36-24a2 2 0 0 0 0-3.329z\"/></svg>\n        <svg class=\"icon pause\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 100 100\"><path d=\"M22.537 8.046h17.791c1.104 0 2.003.898 2.003 1.993v79.912a2.005 2.005 0 0 1-2.003 2.003h-17.79a2.005 2.005 0 0 1-2.003-2.003V10.04c0-1.095.898-1.993 2.002-1.993zM59.672 8.046h17.8c1.095 0 1.993.898 1.993 1.993v79.912a2.003 2.003 0 0 1-1.993 2.003h-17.8a1.997 1.997 0 0 1-1.993-2.003V10.04c0-1.095.889-1.993 1.993-1.993z\"/></svg>\n      </div>\n\n      <div class=\"player__next\" (click)=\"onFastForwardHandler()\">\n        <svg class=\"icon\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 100 100\"><path d=\"M26.695 34.434v31.132L54.5 49.998z\"/><path d=\"M24.07 34.434v31.132c0 2.018 2.222 3.234 3.95 2.267l27.804-15.568c1.706-.955 1.707-3.578 0-4.533L28.02 32.168c-2.957-1.655-5.604 2.88-2.649 4.533l27.805 15.564v-4.533L25.371 63.3l3.95 2.267V34.435c-.001-3.387-5.251-3.387-5.251-.001z\"/><g><path d=\"M55.5 34.434v31.132l27.805-15.568z\"/><path d=\"M52.875 34.434v31.132c0 2.018 2.222 3.234 3.949 2.267 9.27-5.189 18.537-10.379 27.805-15.568 1.705-.955 1.705-3.578 0-4.533L56.824 32.168c-2.957-1.655-5.604 2.88-2.648 4.533l27.803 15.564v-4.533L54.176 63.3l3.949 2.267V34.435c0-3.387-5.25-3.387-5.25-.001z\"/></g></svg>\n      </div>\n    </div>\n  </div>\n  <div class=\"player__timeline\">\n    <p class=\"player__author\">\n      {{ author }}\n    </p>\n    <p class=\"player__song\">\n      {{ song }}\n    </p>\n\n    <button class=\"player__timelineHit\" (click)=\"onChangeTimelinekHandler($event)\">\n      <div class=\"player__timelineBar\" #timelineBar>\n        <div id=\"playhead\" [ngStyle]=\"{width: progression+'%'}\"></div>\n      </div>\n    </button>\n  </div>\n</div>\n","import {IoPlayerComponent} from './io-player/io-player.component';\nimport {BrowserModule} from '@angular/platform-browser';\nimport {DoBootstrap, Injector, NgModule} from '@angular/core';\nimport {createCustomElement} from '@angular/elements';\n\n@NgModule({\n  declarations: [\n    IoPlayerComponent\n  ],\n  entryComponents: [\n    IoPlayerComponent\n  ],\n  imports: [\n    BrowserModule\n  ],\n  exports: [\n    IoPlayerComponent\n  ],\n  providers: [],\n  bootstrap: []\n})\nexport class IoPlayerModule implements DoBootstrap {\n  constructor(private injector: Injector) {\n    const customElement = createCustomElement(IoPlayerComponent, {injector});\n    customElements.define('io-player', customElement);\n  }\n\n  // eslint-disable-next-line  @angular-eslint/no-empty-lifecycle-method\n  ngDoBootstrap() {\n  }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":"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"}