From 6eb1cfaea16a5cfb37b78eae49408adb3e833b82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1vid=20Danyi?= Date: Thu, 19 Apr 2018 17:06:08 +0200 Subject: [PATCH] * default routes and redirects added * timers refactored into a timer service from the app.component * settings service now provides observable setting changes * slideshow is now working * commit-tracker style changed to dark look, colored lines were removed * dashboard menu order changed * slide/committracker is now animated --- src/app/admin/admin-routing.module.ts | 5 ++ .../admin/dashboard/dashboard.component.html | 26 +++---- .../slide-list/slide-list.component.html | 2 +- .../admin/team-list/team-list.component.html | 2 +- src/app/app-routing.module.ts | 6 +- src/app/app.component.ts | 68 ++----------------- src/app/app.module.ts | 3 +- .../commit-tracker.component.css | 4 ++ .../commit-tracker.component.html | 6 +- .../commit-tracker.component.ts | 51 +++++++------- src/app/display/display-routing.module.ts | 20 ++++++ .../display/settings/settings.component.html | 2 +- src/app/display/slide-show.service.ts | 19 +++--- .../slide-show/slide-show.component.ts | 4 +- src/app/display/slide/slide.component.css | 13 ++-- src/app/shared/service/settings.service.ts | 18 ++++- src/app/shared/service/timer.service.spec.ts | 15 ++++ src/app/shared/service/timer.service.ts | 62 +++++++++++++++++ src/app/shared/slide-in-out-animation.ts | 11 ++- 19 files changed, 203 insertions(+), 134 deletions(-) create mode 100644 src/app/shared/service/timer.service.spec.ts create mode 100644 src/app/shared/service/timer.service.ts diff --git a/src/app/admin/admin-routing.module.ts b/src/app/admin/admin-routing.module.ts index 414e388..8150c0f 100644 --- a/src/app/admin/admin-routing.module.ts +++ b/src/app/admin/admin-routing.module.ts @@ -14,6 +14,11 @@ import { DashboardComponent } from './dashboard/dashboard.component'; const routes: Routes = [ { path: 'admin', + redirectTo: '/dashboard', + pathMatch: 'full' + // canActivate: [AuthGuardService, RoleGuardService], + }, { + path: 'dashboard', component: DashboardComponent, // canActivate: [AuthGuardService, RoleGuardService], }, { diff --git a/src/app/admin/dashboard/dashboard.component.html b/src/app/admin/dashboard/dashboard.component.html index 3b92002..4c7539e 100644 --- a/src/app/admin/dashboard/dashboard.component.html +++ b/src/app/admin/dashboard/dashboard.component.html @@ -4,12 +4,12 @@
-
Commit tracker
+
Start slideshow
Local
-

View commits of the current configured team members.

+

Starts playing the slideshow on this device.

@@ -24,17 +24,6 @@
- -
-
Teams
-
- Global -
-
-

Create teams, manage team members.

-
-
-
Slides
@@ -46,5 +35,16 @@
+ +
+
Teams
+
+ Global +
+
+

Create teams, manage team members.

+
+
+
diff --git a/src/app/admin/slide-list/slide-list.component.html b/src/app/admin/slide-list/slide-list.component.html index 2694ef6..26dd9c2 100644 --- a/src/app/admin/slide-list/slide-list.component.html +++ b/src/app/admin/slide-list/slide-list.component.html @@ -3,7 +3,7 @@ New slide Back to dashboard + [routerLink]="['/dashboard']">Back to dashboard diff --git a/src/app/admin/team-list/team-list.component.html b/src/app/admin/team-list/team-list.component.html index 21a36a8..f51f43f 100644 --- a/src/app/admin/team-list/team-list.component.html +++ b/src/app/admin/team-list/team-list.component.html @@ -3,7 +3,7 @@ New teamBack to dashboard + [routerLink]="['/dashboard']">Back to dashboard
diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index 4c70708..848fed2 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -6,8 +6,10 @@ import { Routes, RouterModule } from '@angular/router'; // import { PageNotFoundComponent } from "./page-not-found/page-not-found.component"; const routes: Routes = [ - // {path: '', component: HomeComponent, canActivate: [AuthGuardService]}, - // {path: '**', component: PageNotFoundComponent}, + {path: '', redirectTo: '/dashboard', pathMatch: 'full'}, + {path: '**', redirectTo: '/dashboard', pathMatch: 'full'} + // {path: '', component: HomeComponent, canActivate: [AuthGuardService]}, + // {path: '**', component: PageNotFoundComponent}, ]; @NgModule({ diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 9674678..2ba89df 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,70 +1,12 @@ -import { Component, OnDestroy, OnInit } from '@angular/core'; -import { Subscription } from 'rxjs/Subscription'; -import { CommitTrackerService } from './shared/service/commit-tracker.service'; -import { SettingsService } from './shared/service/settings.service'; -import { SelfUpdaterService } from './shared/service/self-updater.service'; -import { ActivationEnd, Router } from '@angular/router'; -import { Subject } from 'rxjs/Subject'; -import { TimerObservable } from 'rxjs/observable/TimerObservable'; -import 'rxjs/add/operator/filter'; -import 'rxjs/add/operator/switchMap'; - - -const TIMER_UPDATE_POLL_INTERVAL = 30000; -const TIMER_COMMITTRACKER_REFRESH = 5000; +import { Component, OnInit } from '@angular/core'; +import { TimerService } from './shared/service/timer.service'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) -export class AppComponent implements OnInit, OnDestroy { - private selfUpdateCheckerTimer: Subscription; - private refreshCommitTrackerTimer: Subscription; - private slideshowTimer: Subscription; - private autoSwitch = false; - - constructor(private commitTrackerService: CommitTrackerService, - private settings: SettingsService, - private selfUpdaterService: SelfUpdaterService, - private router: Router) {} - - public ngOnInit() { - const timerSUC = TimerObservable.create(TIMER_UPDATE_POLL_INTERVAL, TIMER_UPDATE_POLL_INTERVAL); - this.selfUpdateCheckerTimer = timerSUC.subscribe(() => { - this.selfUpdaterService.checkAndReloadIfNecessary(); - }); - - const timerCT = TimerObservable.create(TIMER_COMMITTRACKER_REFRESH, TIMER_COMMITTRACKER_REFRESH); - this.refreshCommitTrackerTimer = timerCT.subscribe(() => { - this.commitTrackerService.getTeamCommits(this.settings.team.members.map(member => member.signum)); - }); - - const timerSS = new Subject(); - this.slideshowTimer = timerSS.switchMap((period: number) => TimerObservable.create(period)) - .subscribe(() => { - this.changeSlide(timerSS); - }); - timerSS.next(this.settings.slideInterval); - - this.autoSwitch = false; - this.router.events - .filter(event => event instanceof ActivationEnd) - .subscribe((event: ActivationEnd) => { - this.autoSwitch = !!event.snapshot.data.autoSwitchable; - }); - } - - public ngOnDestroy() { - this.refreshCommitTrackerTimer.unsubscribe(); - this.selfUpdateCheckerTimer.unsubscribe(); - this.slideshowTimer.unsubscribe(); - } - - private changeSlide(timer: Subject) { - if (this.autoSwitch) { - console.log('Slide should have changed here'); - } - timer.next(this.settings.slideInterval); - } +export class AppComponent implements OnInit { + constructor(private timerService: TimerService) {} + public ngOnInit() {} } diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 07339e7..f12ac3c 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -14,6 +14,7 @@ import { DisplayModule } from './display/display.module'; import { CommitTrackerService } from './shared/service/commit-tracker.service'; import { SettingsService } from './shared/service/settings.service'; import { SelfUpdaterService } from './shared/service/self-updater.service'; +import { TimerService } from './shared/service/timer.service'; @NgModule({ declarations: [ @@ -29,7 +30,7 @@ import { SelfUpdaterService } from './shared/service/self-updater.service'; AdminModule, AppRoutingModule, // must be last RouterModule import for ** route to work ], - providers: [TeamService, SlideService, CommitTrackerService, SettingsService, SelfUpdaterService], + providers: [TeamService, SlideService, CommitTrackerService, SettingsService, SelfUpdaterService, TimerService], bootstrap: [AppComponent] }) export class AppModule { diff --git a/src/app/display/commit-tracker/commit-tracker.component.css b/src/app/display/commit-tracker/commit-tracker.component.css index 3618bc0..71d23b8 100644 --- a/src/app/display/commit-tracker/commit-tracker.component.css +++ b/src/app/display/commit-tracker/commit-tracker.component.css @@ -1,3 +1,7 @@ +:host { + background-color: #444; +} + .ui.label.inprogress { position: relative; } diff --git a/src/app/display/commit-tracker/commit-tracker.component.html b/src/app/display/commit-tracker/commit-tracker.component.html index 911fe85..e0b27bc 100644 --- a/src/app/display/commit-tracker/commit-tracker.component.html +++ b/src/app/display/commit-tracker/commit-tracker.component.html @@ -1,5 +1,5 @@ -
-
+
+
@@ -12,7 +12,7 @@ - + diff --git a/src/app/display/commit-tracker/commit-tracker.component.ts b/src/app/display/commit-tracker/commit-tracker.component.ts index 8a25fad..86ad84a 100644 --- a/src/app/display/commit-tracker/commit-tracker.component.ts +++ b/src/app/display/commit-tracker/commit-tracker.component.ts @@ -1,23 +1,35 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, HostBinding, OnDestroy, OnInit } from '@angular/core'; import { Title } from '@angular/platform-browser'; import { ActivatedRoute } from '@angular/router'; +import { Subscription } from 'rxjs/Subscription'; +import { TimerObservable } from 'rxjs/observable/TimerObservable'; +import { slideInOutAnimation } from '../../shared/slide-in-out-animation'; import { CommitTrackerService } from '../../shared/service/commit-tracker.service'; +import { SettingsService } from '../../shared/service/settings.service'; import { Commit } from '../../shared/commit'; import { CommitStatus } from '../../shared/commit-status.enum'; import { Result } from '../../shared/result.enum'; import { Build } from '../../shared/build'; +const TIMER_COMMITTRACKER_REFRESH = 10000; + @Component({ selector: 'app-commit-tracker', templateUrl: './commit-tracker.component.html', - styleUrls: ['./commit-tracker.component.css'] + styleUrls: ['./commit-tracker.component.css'], + animations: [slideInOutAnimation] }) -export class CommitTrackerComponent implements OnInit { +export class CommitTrackerComponent implements OnInit, OnDestroy { public CommitStatus = CommitStatus; + private refreshCommitTrackerTimer: Subscription; + + @HostBinding('@slideInOutAnimation') + slideIn = false; constructor(private commitTrackerService: CommitTrackerService, + private settings: SettingsService, private titleService: Title, private route: ActivatedRoute) { } @@ -25,6 +37,16 @@ export class CommitTrackerComponent implements OnInit { ngOnInit() { this.titleService.setTitle('Commit-tracker : MTAStv'); this.route.data.subscribe((data: { commits: Array }) => this.commits = data.commits); + + const timerCT = TimerObservable.create(TIMER_COMMITTRACKER_REFRESH, TIMER_COMMITTRACKER_REFRESH); + this.refreshCommitTrackerTimer = timerCT.subscribe(() => { + this.commitTrackerService.getTeamCommits(this.settings.team.members.map(member => member.signum)) + .subscribe(commits => this.commits = commits); + }); + } + + ngOnDestroy() { + this.refreshCommitTrackerTimer.unsubscribe(); } get commits(): Array { @@ -118,27 +140,4 @@ export class CommitTrackerComponent implements OnInit { return false; } } - - public rowClasses(commit: Commit) { - return { - positive: this.isAllOk(commit), - negative: this.hasAnyFailure(commit) - }; - } - - private isAllOk(commit: Commit) { - return [ - commit.cfl_result, - commit.sfl_result, - commit.nfl_result, - ].every(result => result === Result.Success); - } - - private hasAnyFailure(commit: Commit) { - return [ - commit.cfl_result, - commit.sfl_result, - commit.nfl_result, - ].some(result => result === Result.Failure); - } } diff --git a/src/app/display/display-routing.module.ts b/src/app/display/display-routing.module.ts index 5d6c6a6..22edf1e 100644 --- a/src/app/display/display-routing.module.ts +++ b/src/app/display/display-routing.module.ts @@ -16,6 +16,26 @@ const routes: Routes = [ resolve: { slide: SlideResolverService, }, + data: { + autoSwitchable: false + } + }, { + path: 'slideshow-odd/:id', + component: SlideShowComponent, + // canActivate: [AuthGuardService, RoleGuardService], + resolve: { + slide: SlideResolverService, + }, + data: { + autoSwitchable: true + } + }, { + path: 'slideshow-even/:id', + component: SlideShowComponent, + // canActivate: [AuthGuardService, RoleGuardService], + resolve: { + slide: SlideResolverService, + }, data: { autoSwitchable: true } diff --git a/src/app/display/settings/settings.component.html b/src/app/display/settings/settings.component.html index d451423..afce8b9 100644 --- a/src/app/display/settings/settings.component.html +++ b/src/app/display/settings/settings.component.html @@ -25,6 +25,6 @@ Back to dashboard + [routerLink]="['/dashboard']">Back to dashboard diff --git a/src/app/display/slide-show.service.ts b/src/app/display/slide-show.service.ts index 24dfe15..386b7ba 100644 --- a/src/app/display/slide-show.service.ts +++ b/src/app/display/slide-show.service.ts @@ -7,24 +7,28 @@ import { SettingsService } from '../shared/service/settings.service'; @Injectable() export class SlideShowService { - private currentSlideIndex = 0; + private oddEven = false; + private currentSlideIndex = -1; private slides: Array = []; constructor(private slideService: SlideService, private settingsService: SettingsService, private router: Router) { - } - - public init() { - this.router.navigate(['/commit-tracker']); + this.reloadSlides(); } public nextSlide() { if (this.currentSlideIndex === this.slides.length - 1) { + this.currentSlideIndex = -1; + this.reloadSlides(); this.router.navigate(['/commit-tracker']); } else { + this.oddEven = !this.oddEven; this.currentSlideIndex++; - this.router.navigate(['/slideshow', this.slides[this.currentSlideIndex]]); + this.router.navigate([ + this.oddEven ? '/slideshow-odd' : '/slideshow-even', + this.slides[this.currentSlideIndex].id + ]); } } @@ -32,9 +36,8 @@ export class SlideShowService { const team = this.settingsService.team; this.slideService.list().subscribe( slides => this.slides = slides.filter( - slide => slide.team.id === team.id + slide => slide.team === null || slide.team.id === team.id ) ); } - } diff --git a/src/app/display/slide-show/slide-show.component.ts b/src/app/display/slide-show/slide-show.component.ts index c2b10f0..297efac 100644 --- a/src/app/display/slide-show/slide-show.component.ts +++ b/src/app/display/slide-show/slide-show.component.ts @@ -17,9 +17,7 @@ export class SlideShowComponent implements OnInit { public slide: Slide; @HostBinding('@slideInOutAnimation') - get slideIn() { - return ''; - } + slideIn = true; constructor(private route: ActivatedRoute, private titleService: Title) { diff --git a/src/app/display/slide/slide.component.css b/src/app/display/slide/slide.component.css index 333951d..f408d92 100644 --- a/src/app/display/slide/slide.component.css +++ b/src/app/display/slide/slide.component.css @@ -1,10 +1,11 @@ :host { - position: absolute; + display: block; top: 0; left: 0; right: 0; bottom: 0; - z-index: 1; + width: 100%; + height: 100%; background: #222; font-family: "Source Sans Pro", Helvetica, sans-serif; font-size: 42px; @@ -13,7 +14,9 @@ padding: 4rem; text-align: center; } - +:host ::ng-deep div.present { + max-height: 100%; +} /********************************************* * HEADERS *********************************************/ @@ -53,8 +56,10 @@ :host ::ng-deep img, :host ::ng-deep video, :host ::ng-deep iframe { + object-fit: scale-down; max-width: 95%; - max-height: 95%; } + max-height: 95%; +} :host ::ng-deep strong, :host ::ng-deep b { diff --git a/src/app/shared/service/settings.service.ts b/src/app/shared/service/settings.service.ts index 01a48c2..727a3eb 100644 --- a/src/app/shared/service/settings.service.ts +++ b/src/app/shared/service/settings.service.ts @@ -1,4 +1,6 @@ import { Injectable } from '@angular/core'; +import { Observable } from 'rxjs/Observable'; +import { Subject } from 'rxjs/Subject'; import { Team } from '../team'; const DEFAULT_SLIDE_INTERVAL = 30000; @@ -9,8 +11,10 @@ const SELECTED_TEAM_KEY = 'team'; @Injectable() export class SettingsService { - constructor() { - } + private teamSubject: Subject = new Subject(); + private intervalSubject: Subject = new Subject(); + + constructor() {} get team(): Team { try { @@ -23,6 +27,7 @@ export class SettingsService { set team(team: Team) { localStorage.setItem(SELECTED_TEAM_KEY, JSON.stringify(team)); + this.teamSubject.next(team); } get slideInterval(): number { @@ -36,5 +41,14 @@ export class SettingsService { set slideInterval(interval: number) { localStorage.setItem(SLIDE_INTERVAL_KEY, JSON.stringify(interval)); + this.intervalSubject.next(interval); + } + + get slideIntervalChanged(): Observable { + return this.intervalSubject.asObservable(); + } + + get teamChanged(): Observable { + return this.teamSubject.asObservable(); } } diff --git a/src/app/shared/service/timer.service.spec.ts b/src/app/shared/service/timer.service.spec.ts new file mode 100644 index 0000000..b66bcb8 --- /dev/null +++ b/src/app/shared/service/timer.service.spec.ts @@ -0,0 +1,15 @@ +import { TestBed, inject } from '@angular/core/testing'; + +import { TimerService } from './timer.service'; + +describe('TimerService', () => { + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [TimerService] + }); + }); + + it('should be created', inject([TimerService], (service: TimerService) => { + expect(service).toBeTruthy(); + })); +}); diff --git a/src/app/shared/service/timer.service.ts b/src/app/shared/service/timer.service.ts new file mode 100644 index 0000000..b2a972f --- /dev/null +++ b/src/app/shared/service/timer.service.ts @@ -0,0 +1,62 @@ +import { Injectable, OnDestroy } from '@angular/core'; +import { Subject } from 'rxjs/Subject'; +import { SettingsService } from './settings.service'; +import { SelfUpdaterService } from './self-updater.service'; +import { TimerObservable } from 'rxjs/observable/TimerObservable'; +import { Subscription } from 'rxjs/Subscription'; +import { ActivationEnd, Router } from '@angular/router'; +import { SlideShowService } from '../../display/slide-show.service'; +import 'rxjs/add/operator/filter'; +import 'rxjs/add/operator/switchMap'; + +const TIMER_UPDATE_POLL_INTERVAL = 30000; + +@Injectable() +export class TimerService implements OnDestroy { + private autoSwitch = false; + private slideShowTimer: Subscription; + private selfUpdateCheckerTimer: Subscription; + private slideTimerSubject: Subject = new Subject(); + private slideIntervalSubscription: Subscription; + + constructor(private settings: SettingsService, + private selfUpdaterService: SelfUpdaterService, + private router: Router, + private slideShowService: SlideShowService) { + + const timerSUC = TimerObservable.create(TIMER_UPDATE_POLL_INTERVAL, TIMER_UPDATE_POLL_INTERVAL); + this.selfUpdateCheckerTimer = timerSUC.subscribe(() => { + this.selfUpdaterService.checkAndReloadIfNecessary(); + }); + + this.slideShowTimer = this.slideTimerSubject.switchMap((period: number) => TimerObservable.create(period)) + .subscribe(() => this.changeSlide()); + this.setSlideTimer(this.settings.slideInterval); + + this.autoSwitch = false; + this.router.events + .filter(event => event instanceof ActivationEnd) + .subscribe((event: ActivationEnd) => this.autoSwitch = !!event.snapshot.data.autoSwitchable); + + this.slideIntervalSubscription = this.settings.slideIntervalChanged.subscribe( + interval => this.setSlideTimer(interval) + ); + } + + public ngOnDestroy() { + this.slideShowTimer.unsubscribe(); + this.selfUpdateCheckerTimer.unsubscribe(); + this.slideIntervalSubscription.unsubscribe(); + } + + private changeSlide() { + if (this.autoSwitch) { + this.slideShowService.nextSlide(); + } + this.setSlideTimer(this.settings.slideInterval); + } + + public setSlideTimer(delay: number) { + this.slideTimerSubject.next(delay); + } +} diff --git a/src/app/shared/slide-in-out-animation.ts b/src/app/shared/slide-in-out-animation.ts index a0dfcc2..2ccc937 100644 --- a/src/app/shared/slide-in-out-animation.ts +++ b/src/app/shared/slide-in-out-animation.ts @@ -17,27 +17,26 @@ export const slideInOutAnimation = // route 'enter' transition transition(':enter', [ - // styles at start of transition style({ // start with the content positioned off the right of the screen, // -400% is required instead of -100% because the negative position adds to the width of the element - right: '-400%' + transform: 'translateX(100%)' }), // animation and styles at end of transition - animate('.5s ease-in-out', style({ + animate('.75s cubic-bezier(0.175, 0.885, 0.32, 1.275)', style({ // transition the right position to 0 which slides the content into view - right: 0 + transform: 'translateX(0)' })) ]), // route 'leave' transition transition(':leave', [ // animation and styles at end of transition - animate('.5s ease-in-out', style({ + animate('.75s cubic-bezier(0.175, 0.885, 0.32, 1.275)', style({ // transition the right position to -400% which slides the content out of view - right: '-400%' + transform: 'translateX(-100%)' })) ]) ]);
Owner
{{commit.owner}} {{commit.gerrit_time}} {{commit.gerrit_change_subject}}