Skip to content

Commit

Permalink
Merge branch 'brandom-fix-vg-scrub-bar-hide'
Browse files Browse the repository at this point in the history
  • Loading branch information
Elecash committed Mar 12, 2017
2 parents 114b029 + 796dc5f commit d28461f
Show file tree
Hide file tree
Showing 7 changed files with 175 additions and 17 deletions.
4 changes: 3 additions & 1 deletion src/controls/controls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { VgScrubBarCuePoints } from './vg-scrub-bar/vg-scrub-bar-cue-points/vg-s
import { VgScrubBarCurrentTime } from './vg-scrub-bar/vg-scrub-bar-current-time/vg-scrub-bar-current-time';
import { VgTimeDisplay, VgUtcPipe } from './vg-time-display/vg-time-display';
import { VgTrackSelector } from './vg-track-selector/vg-track-selector';
import { VgControlsHidden } from './../core/services/vg-controls-hidden';

@NgModule({
imports: [ CommonModule ],
Expand Down Expand Up @@ -44,7 +45,8 @@ import { VgTrackSelector } from './vg-track-selector/vg-track-selector';
VgTimeDisplay,
VgUtcPipe,
VgTrackSelector
]
],
providers: [ VgControlsHidden ]
})
export class VgControlsModule {
}
54 changes: 49 additions & 5 deletions src/controls/vg-controls.spec.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
import {VgControls} from "./vg-controls";
import {VgControlsHidden} from './../core/services/vg-controls-hidden';
import {ElementRef} from "@angular/core";
import {VgAPI} from "../core/services/vg-api";
import {Observable} from "rxjs/Observable";

import 'rxjs/add/observable/fromEvent';
import { VgStates } from '../core/states/vg-states';

describe('Controls Bar', () => {
let controls:VgControls;
let ref:ElementRef;
let api:VgAPI;
let hidden: VgControlsHidden;

beforeEach(() => {
jasmine.clock().uninstall();
jasmine.clock().install();

api = new VgAPI();
hidden = new VgControlsHidden();

ref = {
nativeElement: {
Expand All @@ -24,7 +28,7 @@ describe('Controls Bar', () => {
}
};

controls = new VgControls(api, ref);
controls = new VgControls(api, ref, hidden);
});

afterEach(() => {
Expand All @@ -44,8 +48,8 @@ describe('Controls Bar', () => {

controls.ngOnInit();

expect(Observable.fromEvent).toHaveBeenCalledWith(api.videogularElement, 'mouseenter');
expect(Observable.fromEvent).toHaveBeenCalledWith(api.videogularElement, 'mouseleave');
expect(Observable.fromEvent).toHaveBeenCalledWith(api.videogularElement, 'mousemove');
expect(Observable.fromEvent).toHaveBeenCalledWith(api.videogularElement, 'touchstart');
});

it('Should hide controls after view init', () => {
Expand All @@ -70,23 +74,42 @@ describe('Controls Bar', () => {

it('Should show controls', () => {
spyOn(window, 'clearTimeout').and.callFake(() => {});
spyOn(hidden, 'state').and.callFake(() => {});

controls.show();

expect(window.clearTimeout).toHaveBeenCalled();
expect(controls.hideControls).toBe(false);
expect(hidden.state).toHaveBeenCalledWith(false);
});

it('Should hide controls', () => {
it('Should hide controls when is playing', () => {
spyOn(hidden, 'state').and.callFake(() => {});

controls.vgAutohide = true;
api.medias = [{state: VgStates.VG_PLAYING}];

controls.hide();

jasmine.clock().tick(3100);
expect(controls.hideControls).toBe(true);
expect(hidden.state).toHaveBeenCalledWith(true);
});

it('Should not hide controls if player is paused', () => {
controls.hideControls = false;
controls.vgAutohide = false;

controls.vgAutohide = true;
api.medias = [{state: VgStates.VG_PAUSED}];

controls.hide();

jasmine.clock().tick(3100);
expect(controls.hideControls).toBe(false);
});

it('Should not hide controls', () => {
it('Should not hide controls if autohide is false', () => {
controls.hideControls = false;
controls.vgAutohide = false;

Expand All @@ -95,4 +118,25 @@ describe('Controls Bar', () => {
jasmine.clock().tick(3100);
expect(controls.hideControls).toBe(false);
});

it('Should start hiding controls if media is playing', () => {
spyOn(controls, 'hide').and.callFake(() => {});

controls.vgAutohide = true;

controls.onPlay();

expect(controls.hide).toHaveBeenCalled();
});

it('Should show controls if media is paused', () => {
spyOn(hidden, 'state').and.callFake(() => {});

controls.vgAutohide = true;

controls.onPause();

expect(controls.hideControls).toBe(false);
expect(hidden.state).toHaveBeenCalledWith(false);
});
});
38 changes: 30 additions & 8 deletions src/controls/vg-controls.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { Component, Input, OnInit, ElementRef, HostBinding, AfterViewInit, ViewEncapsulation } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { VgAPI } from '../core/services/vg-api';
import { VgControlsHidden } from './../core/services/vg-controls-hidden';
import 'rxjs/add/observable/fromEvent';
import { VgStates } from '../core/states/vg-states';

@Component({
selector: 'vg-controls',
Expand Down Expand Up @@ -40,17 +42,18 @@ export class VgControls implements OnInit, AfterViewInit {
@Input() vgAutohideTime: number = 3;

private timer: any;
private hideTimer: any;

constructor(private API: VgAPI, private ref: ElementRef) {
constructor(private API: VgAPI, private ref: ElementRef, private hidden: VgControlsHidden) {
this.elem = ref.nativeElement;
}

ngOnInit() {
let mouseEnter = Observable.fromEvent(this.API.videogularElement, 'mouseenter');
mouseEnter.subscribe(this.show.bind(this));
let mouseMove = Observable.fromEvent(this.API.videogularElement, 'mousemove');
mouseMove.subscribe(this.show.bind(this));

let mouseLeave = Observable.fromEvent(this.API.videogularElement, 'mouseleave');
mouseLeave.subscribe(this.hide.bind(this));
let touchStart = Observable.fromEvent(this.API.videogularElement, 'touchstart');
touchStart.subscribe(this.show.bind(this));

if (this.API.isPlayerReady) {
this.onPlayerReady();
Expand All @@ -63,6 +66,8 @@ export class VgControls implements OnInit, AfterViewInit {
onPlayerReady() {
this.target = this.API.getMediaById(this.vgFor);

this.target.subscriptions.play.subscribe(this.onPlay.bind(this));
this.target.subscriptions.pause.subscribe(this.onPause.bind(this));
this.target.subscriptions.startAds.subscribe(this.onStartAds.bind(this));
this.target.subscriptions.endAds.subscribe(this.onEndAds.bind(this));
}
Expand All @@ -76,6 +81,18 @@ export class VgControls implements OnInit, AfterViewInit {
}
}

onPlay() {
if (this.vgAutohide) {
this.hide();
}
}

onPause() {
clearTimeout(this.timer);
this.hideControls = false;
this.hidden.state(false);
}

onStartAds() {
this.isAdsPlaying = 'none';
}
Expand All @@ -94,11 +111,16 @@ export class VgControls implements OnInit, AfterViewInit {
show() {
clearTimeout(this.timer);
this.hideControls = false;
this.hidden.state(false);
this.hideAsync();
}

private hideAsync() {
this.timer = setTimeout(() => {
this.hideControls = true;
}, this.vgAutohideTime * 1000);
if (this.API.state === VgStates.VG_PLAYING) {
this.timer = setTimeout(() => {
this.hideControls = true;
this.hidden.state(true);
}, this.vgAutohideTime * 1000);
}
}
}
16 changes: 15 additions & 1 deletion src/controls/vg-scrub-bar/vg-scrub-bar.spec.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import {VgScrubBar} from "./vg-scrub-bar";
import {VgAPI} from "../../core/services/vg-api";
import {ElementRef} from "@angular/core";
import {VgControlsHidden} from './../../core/services/vg-controls-hidden';

describe('Scrub bar', () => {
let scrubBar:VgScrubBar;
let ref:ElementRef;
let api:VgAPI;
let vgControlsHiddenState: VgControlsHidden;

beforeEach(() => {
ref = {
Expand All @@ -18,8 +20,10 @@ describe('Scrub bar', () => {
};

api = new VgAPI();
vgControlsHiddenState = new VgControlsHidden();

scrubBar = new VgScrubBar(ref, api);

scrubBar = new VgScrubBar(ref, api, vgControlsHiddenState);
});

it('Should get media by id on init', () => {
Expand All @@ -31,6 +35,16 @@ describe('Scrub bar', () => {
expect(api.getMediaById).toHaveBeenCalledWith('test');
});

it('Should show scrub bar', () => {
vgControlsHiddenState.state(false);
expect(scrubBar.hideScrubBar).toBe(false);
});

it('Should hide scrub bar', () => {
vgControlsHiddenState.state(true);
expect(scrubBar.hideScrubBar).toBe(true);
});

describe('onMouseDownScrubBar', () => {
it('should call API seekTime 10 when offsetX is 20 and scrollWidth is 200', () => {
spyOn(api, 'seekTime');
Expand Down
32 changes: 30 additions & 2 deletions src/controls/vg-scrub-bar/vg-scrub-bar.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Component, ElementRef, Input, HostListener, OnInit, ViewEncapsulation } from '@angular/core';
import { Component, ElementRef, Input, HostListener, OnInit, ViewEncapsulation, HostBinding } from '@angular/core';
import { VgAPI } from '../../core/services/vg-api';
import { VgControlsHidden } from './../../core/services/vg-controls-hidden';

@Component({
selector: 'vg-scrub-bar',
Expand All @@ -16,6 +17,11 @@ import { VgAPI } from '../../core/services/vg-api';
align-items: center;
background: rgba(0, 0, 0, 0.75);
z-index: 250;
-webkit-transition: bottom 1s, opacity 0.5s;
-khtml-transition: bottom 1s, opacity 0.5s;
-moz-transition: bottom 1s, opacity 0.5s;
-ms-transition: bottom 1s, opacity 0.5s;
transition: bottom 1s, opacity 0.5s;
}
vg-controls vg-scrub-bar {
Expand All @@ -26,17 +32,35 @@ import { VgAPI } from '../../core/services/vg-api';
flex-grow: 1;
flex-basis: 0;
margin: 0 10px;
-webkit-transition: initial;
-khtml-transition: initial;
-moz-transition: initial;
-ms-transition: initial;
transition: initial;
}
vg-scrub-bar.hide {
bottom: 0px;
opacity: 0;
}
vg-controls vg-scrub-bar.hide {
bottom: initial;
opacity: initial;
}
` ]
})
export class VgScrubBar implements OnInit {
@HostBinding('class.hide') hideScrubBar: boolean = false;

@Input() vgFor: string;

elem: HTMLElement;
target: any;

constructor(ref: ElementRef, public API: VgAPI) {
constructor(ref: ElementRef, public API: VgAPI, vgControlsHiddenState: VgControlsHidden) {
this.elem = ref.nativeElement;
vgControlsHiddenState.isHidden.subscribe(hide => this.onHideScrubBar(hide));
}

ngOnInit() {
Expand All @@ -60,4 +84,8 @@ export class VgScrubBar implements OnInit {
this.target.seekTime(percentage, true);
}
}

onHideScrubBar(hide: boolean) {
this.hideScrubBar = hide;
}
}
30 changes: 30 additions & 0 deletions src/core/services/vg-controls-hidden.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { Observable } from 'rxjs/Observable';
import { VgControlsHidden } from './vg-controls-hidden';

describe('VgControlsHidden Service', () => {
let controlsHidden: VgControlsHidden;

beforeEach(() => {
controlsHidden = new VgControlsHidden();
});

it('Should provide an Observable', () => {
expect(controlsHidden.isHidden).toEqual(jasmine.any(Observable));
});

it('Should set state to true', () => {
controlsHidden.isHidden.subscribe(state => {
expect(state).toBe(true);
});

controlsHidden.state(true);
});

it('Should set state to false', () => {
controlsHidden.isHidden.subscribe(state => {
expect(state).toBe(false);
});

controlsHidden.state(false);
});
});
18 changes: 18 additions & 0 deletions src/core/services/vg-controls-hidden.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Subject } from 'rxjs/Subject';
import { Observable } from 'rxjs/Observable';
import { Injectable } from '@angular/core';

@Injectable()
export class VgControlsHidden {
isHidden: Observable<boolean>;

private isHiddenSubject: Subject<boolean> = new Subject<boolean>();

constructor() {
this.isHidden = this.isHiddenSubject.asObservable();
}

state(hidden: boolean) {
this.isHiddenSubject.next(hidden);
}
}

0 comments on commit d28461f

Please sign in to comment.