* 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
This commit is contained in:
parent
90ddebf46b
commit
6eb1cfaea1
@ -14,6 +14,11 @@ import { DashboardComponent } from './dashboard/dashboard.component';
|
|||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{
|
{
|
||||||
path: 'admin',
|
path: 'admin',
|
||||||
|
redirectTo: '/dashboard',
|
||||||
|
pathMatch: 'full'
|
||||||
|
// canActivate: [AuthGuardService, RoleGuardService],
|
||||||
|
}, {
|
||||||
|
path: 'dashboard',
|
||||||
component: DashboardComponent,
|
component: DashboardComponent,
|
||||||
// canActivate: [AuthGuardService, RoleGuardService],
|
// canActivate: [AuthGuardService, RoleGuardService],
|
||||||
}, {
|
}, {
|
||||||
|
|||||||
@ -4,12 +4,12 @@
|
|||||||
<div class="ui four cards">
|
<div class="ui four cards">
|
||||||
<a class="ui raised yellow card" [routerLink]="['/commit-tracker']">
|
<a class="ui raised yellow card" [routerLink]="['/commit-tracker']">
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="header">Commit tracker</div>
|
<div class="header">Start slideshow</div>
|
||||||
<div class="meta">
|
<div class="meta">
|
||||||
<span class="category">Local</span>
|
<span class="category">Local</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="description">
|
<div class="description">
|
||||||
<p>View commits of the current configured team members.</p>
|
<p>Starts playing the slideshow on this device.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
@ -24,17 +24,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
<a class="ui raised green card" [routerLink]="['/admin/teams']">
|
|
||||||
<div class="content">
|
|
||||||
<div class="header">Teams</div>
|
|
||||||
<div class="meta">
|
|
||||||
<span class="category">Global</span>
|
|
||||||
</div>
|
|
||||||
<div class="description">
|
|
||||||
<p>Create teams, manage team members.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
<a class="ui raised blue card" [routerLink]="['/admin/slides']">
|
<a class="ui raised blue card" [routerLink]="['/admin/slides']">
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="header">Slides</div>
|
<div class="header">Slides</div>
|
||||||
@ -46,5 +35,16 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
|
<a class="ui raised green card" [routerLink]="['/admin/teams']">
|
||||||
|
<div class="content">
|
||||||
|
<div class="header">Teams</div>
|
||||||
|
<div class="meta">
|
||||||
|
<span class="category">Global</span>
|
||||||
|
</div>
|
||||||
|
<div class="description">
|
||||||
|
<p>Create teams, manage team members.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
<a class="ui primary button"
|
<a class="ui primary button"
|
||||||
[routerLink]="['/admin/slide/new']"><i class="plus sign icon"></i>New slide</a>
|
[routerLink]="['/admin/slide/new']"><i class="plus sign icon"></i>New slide</a>
|
||||||
<a class="ui button"
|
<a class="ui button"
|
||||||
[routerLink]="['/admin']"><i class="left angle icon"></i>Back to dashboard</a>
|
[routerLink]="['/dashboard']"><i class="left angle icon"></i>Back to dashboard</a>
|
||||||
<table *ngIf="slides?.length" class="ui large padded celled definition table">
|
<table *ngIf="slides?.length" class="ui large padded celled definition table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
<a class="ui primary button"
|
<a class="ui primary button"
|
||||||
[routerLink]="['/admin/team/new']"><i class="plus sign icon"></i>New team</a>
|
[routerLink]="['/admin/team/new']"><i class="plus sign icon"></i>New team</a>
|
||||||
<a class="ui button"
|
<a class="ui button"
|
||||||
[routerLink]="['/admin']"><i class="left angle icon"></i>Back to dashboard</a>
|
[routerLink]="['/dashboard']"><i class="left angle icon"></i>Back to dashboard</a>
|
||||||
<table *ngIf="teams?.length" class="ui large padded celled definition table">
|
<table *ngIf="teams?.length" class="ui large padded celled definition table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
|||||||
@ -6,8 +6,10 @@ import { Routes, RouterModule } from '@angular/router';
|
|||||||
// import { PageNotFoundComponent } from "./page-not-found/page-not-found.component";
|
// import { PageNotFoundComponent } from "./page-not-found/page-not-found.component";
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
// {path: '', component: HomeComponent, canActivate: [AuthGuardService]},
|
{path: '', redirectTo: '/dashboard', pathMatch: 'full'},
|
||||||
// {path: '**', component: PageNotFoundComponent},
|
{path: '**', redirectTo: '/dashboard', pathMatch: 'full'}
|
||||||
|
// {path: '', component: HomeComponent, canActivate: [AuthGuardService]},
|
||||||
|
// {path: '**', component: PageNotFoundComponent},
|
||||||
];
|
];
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
|
|||||||
@ -1,70 +1,12 @@
|
|||||||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import { Subscription } from 'rxjs/Subscription';
|
import { TimerService } from './shared/service/timer.service';
|
||||||
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;
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-root',
|
selector: 'app-root',
|
||||||
templateUrl: './app.component.html',
|
templateUrl: './app.component.html',
|
||||||
styleUrls: ['./app.component.css']
|
styleUrls: ['./app.component.css']
|
||||||
})
|
})
|
||||||
export class AppComponent implements OnInit, OnDestroy {
|
export class AppComponent implements OnInit {
|
||||||
private selfUpdateCheckerTimer: Subscription;
|
constructor(private timerService: TimerService) {}
|
||||||
private refreshCommitTrackerTimer: Subscription;
|
public ngOnInit() {}
|
||||||
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<number>();
|
|
||||||
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<number>) {
|
|
||||||
if (this.autoSwitch) {
|
|
||||||
console.log('Slide should have changed here');
|
|
||||||
}
|
|
||||||
timer.next(this.settings.slideInterval);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,6 +14,7 @@ import { DisplayModule } from './display/display.module';
|
|||||||
import { CommitTrackerService } from './shared/service/commit-tracker.service';
|
import { CommitTrackerService } from './shared/service/commit-tracker.service';
|
||||||
import { SettingsService } from './shared/service/settings.service';
|
import { SettingsService } from './shared/service/settings.service';
|
||||||
import { SelfUpdaterService } from './shared/service/self-updater.service';
|
import { SelfUpdaterService } from './shared/service/self-updater.service';
|
||||||
|
import { TimerService } from './shared/service/timer.service';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
@ -29,7 +30,7 @@ import { SelfUpdaterService } from './shared/service/self-updater.service';
|
|||||||
AdminModule,
|
AdminModule,
|
||||||
AppRoutingModule, // must be last RouterModule import for ** route to work
|
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]
|
bootstrap: [AppComponent]
|
||||||
})
|
})
|
||||||
export class AppModule {
|
export class AppModule {
|
||||||
|
|||||||
@ -1,3 +1,7 @@
|
|||||||
|
:host {
|
||||||
|
background-color: #444;
|
||||||
|
}
|
||||||
|
|
||||||
.ui.label.inprogress {
|
.ui.label.inprogress {
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
<div class="ui main wide-container">
|
<div class="ui main wide-container dark">
|
||||||
<table *ngIf="commits?.length" class="ui large padded celled table">
|
<table *ngIf="commits?.length" class="ui large padded inverted celled2 table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="collapsing"><i class="user icon"></i>Owner</th>
|
<th class="collapsing"><i class="user icon"></i>Owner</th>
|
||||||
@ -12,7 +12,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr *ngFor="let commit of commits" [ngClass]="rowClasses(commit)">
|
<tr *ngFor="let commit of commits">
|
||||||
<td class="collapsing">{{commit.owner}}</td>
|
<td class="collapsing">{{commit.owner}}</td>
|
||||||
<td class="collapsing">{{commit.gerrit_time}}</td>
|
<td class="collapsing">{{commit.gerrit_time}}</td>
|
||||||
<td>{{commit.gerrit_change_subject}}</td>
|
<td>{{commit.gerrit_change_subject}}</td>
|
||||||
|
|||||||
@ -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 { Title } from '@angular/platform-browser';
|
||||||
import { ActivatedRoute } from '@angular/router';
|
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 { CommitTrackerService } from '../../shared/service/commit-tracker.service';
|
||||||
|
import { SettingsService } from '../../shared/service/settings.service';
|
||||||
import { Commit } from '../../shared/commit';
|
import { Commit } from '../../shared/commit';
|
||||||
import { CommitStatus } from '../../shared/commit-status.enum';
|
import { CommitStatus } from '../../shared/commit-status.enum';
|
||||||
import { Result } from '../../shared/result.enum';
|
import { Result } from '../../shared/result.enum';
|
||||||
import { Build } from '../../shared/build';
|
import { Build } from '../../shared/build';
|
||||||
|
|
||||||
|
const TIMER_COMMITTRACKER_REFRESH = 10000;
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-commit-tracker',
|
selector: 'app-commit-tracker',
|
||||||
templateUrl: './commit-tracker.component.html',
|
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;
|
public CommitStatus = CommitStatus;
|
||||||
|
private refreshCommitTrackerTimer: Subscription;
|
||||||
|
|
||||||
|
@HostBinding('@slideInOutAnimation')
|
||||||
|
slideIn = false;
|
||||||
|
|
||||||
constructor(private commitTrackerService: CommitTrackerService,
|
constructor(private commitTrackerService: CommitTrackerService,
|
||||||
|
private settings: SettingsService,
|
||||||
private titleService: Title,
|
private titleService: Title,
|
||||||
private route: ActivatedRoute) {
|
private route: ActivatedRoute) {
|
||||||
}
|
}
|
||||||
@ -25,6 +37,16 @@ export class CommitTrackerComponent implements OnInit {
|
|||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.titleService.setTitle('Commit-tracker : MTAStv');
|
this.titleService.setTitle('Commit-tracker : MTAStv');
|
||||||
this.route.data.subscribe((data: { commits: Array<Commit> }) => this.commits = data.commits);
|
this.route.data.subscribe((data: { commits: Array<Commit> }) => 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<Commit> {
|
get commits(): Array<Commit> {
|
||||||
@ -118,27 +140,4 @@ export class CommitTrackerComponent implements OnInit {
|
|||||||
return false;
|
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,6 +16,26 @@ const routes: Routes = [
|
|||||||
resolve: {
|
resolve: {
|
||||||
slide: SlideResolverService,
|
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: {
|
data: {
|
||||||
autoSwitchable: true
|
autoSwitchable: true
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,6 +25,6 @@
|
|||||||
</div>
|
</div>
|
||||||
<button type="submit" class="ui positive button"><i class="save outline icon"></i>Save</button>
|
<button type="submit" class="ui positive button"><i class="save outline icon"></i>Save</button>
|
||||||
<a class="ui button"
|
<a class="ui button"
|
||||||
[routerLink]="['/admin']"><i class="left angle icon"></i>Back to dashboard</a>
|
[routerLink]="['/dashboard']"><i class="left angle icon"></i>Back to dashboard</a>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -7,24 +7,28 @@ import { SettingsService } from '../shared/service/settings.service';
|
|||||||
@Injectable()
|
@Injectable()
|
||||||
export class SlideShowService {
|
export class SlideShowService {
|
||||||
|
|
||||||
private currentSlideIndex = 0;
|
private oddEven = false;
|
||||||
|
private currentSlideIndex = -1;
|
||||||
private slides: Array<Slide> = [];
|
private slides: Array<Slide> = [];
|
||||||
|
|
||||||
constructor(private slideService: SlideService,
|
constructor(private slideService: SlideService,
|
||||||
private settingsService: SettingsService,
|
private settingsService: SettingsService,
|
||||||
private router: Router) {
|
private router: Router) {
|
||||||
}
|
this.reloadSlides();
|
||||||
|
|
||||||
public init() {
|
|
||||||
this.router.navigate(['/commit-tracker']);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public nextSlide() {
|
public nextSlide() {
|
||||||
if (this.currentSlideIndex === this.slides.length - 1) {
|
if (this.currentSlideIndex === this.slides.length - 1) {
|
||||||
|
this.currentSlideIndex = -1;
|
||||||
|
this.reloadSlides();
|
||||||
this.router.navigate(['/commit-tracker']);
|
this.router.navigate(['/commit-tracker']);
|
||||||
} else {
|
} else {
|
||||||
|
this.oddEven = !this.oddEven;
|
||||||
this.currentSlideIndex++;
|
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;
|
const team = this.settingsService.team;
|
||||||
this.slideService.list().subscribe(
|
this.slideService.list().subscribe(
|
||||||
slides => this.slides = slides.filter(
|
slides => this.slides = slides.filter(
|
||||||
slide => slide.team.id === team.id
|
slide => slide.team === null || slide.team.id === team.id
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,9 +17,7 @@ export class SlideShowComponent implements OnInit {
|
|||||||
public slide: Slide;
|
public slide: Slide;
|
||||||
|
|
||||||
@HostBinding('@slideInOutAnimation')
|
@HostBinding('@slideInOutAnimation')
|
||||||
get slideIn() {
|
slideIn = true;
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(private route: ActivatedRoute,
|
constructor(private route: ActivatedRoute,
|
||||||
private titleService: Title) {
|
private titleService: Title) {
|
||||||
|
|||||||
@ -1,10 +1,11 @@
|
|||||||
:host {
|
:host {
|
||||||
position: absolute;
|
display: block;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
z-index: 1;
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
background: #222;
|
background: #222;
|
||||||
font-family: "Source Sans Pro", Helvetica, sans-serif;
|
font-family: "Source Sans Pro", Helvetica, sans-serif;
|
||||||
font-size: 42px;
|
font-size: 42px;
|
||||||
@ -13,7 +14,9 @@
|
|||||||
padding: 4rem;
|
padding: 4rem;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
:host ::ng-deep div.present {
|
||||||
|
max-height: 100%;
|
||||||
|
}
|
||||||
/*********************************************
|
/*********************************************
|
||||||
* HEADERS
|
* HEADERS
|
||||||
*********************************************/
|
*********************************************/
|
||||||
@ -53,8 +56,10 @@
|
|||||||
:host ::ng-deep img,
|
:host ::ng-deep img,
|
||||||
:host ::ng-deep video,
|
:host ::ng-deep video,
|
||||||
:host ::ng-deep iframe {
|
:host ::ng-deep iframe {
|
||||||
|
object-fit: scale-down;
|
||||||
max-width: 95%;
|
max-width: 95%;
|
||||||
max-height: 95%; }
|
max-height: 95%;
|
||||||
|
}
|
||||||
|
|
||||||
:host ::ng-deep strong,
|
:host ::ng-deep strong,
|
||||||
:host ::ng-deep b {
|
:host ::ng-deep b {
|
||||||
|
|||||||
@ -1,4 +1,6 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
|
import { Observable } from 'rxjs/Observable';
|
||||||
|
import { Subject } from 'rxjs/Subject';
|
||||||
import { Team } from '../team';
|
import { Team } from '../team';
|
||||||
|
|
||||||
const DEFAULT_SLIDE_INTERVAL = 30000;
|
const DEFAULT_SLIDE_INTERVAL = 30000;
|
||||||
@ -9,8 +11,10 @@ const SELECTED_TEAM_KEY = 'team';
|
|||||||
@Injectable()
|
@Injectable()
|
||||||
export class SettingsService {
|
export class SettingsService {
|
||||||
|
|
||||||
constructor() {
|
private teamSubject: Subject<Team> = new Subject<Team>();
|
||||||
}
|
private intervalSubject: Subject<number> = new Subject<number>();
|
||||||
|
|
||||||
|
constructor() {}
|
||||||
|
|
||||||
get team(): Team {
|
get team(): Team {
|
||||||
try {
|
try {
|
||||||
@ -23,6 +27,7 @@ export class SettingsService {
|
|||||||
|
|
||||||
set team(team: Team) {
|
set team(team: Team) {
|
||||||
localStorage.setItem(SELECTED_TEAM_KEY, JSON.stringify(team));
|
localStorage.setItem(SELECTED_TEAM_KEY, JSON.stringify(team));
|
||||||
|
this.teamSubject.next(team);
|
||||||
}
|
}
|
||||||
|
|
||||||
get slideInterval(): number {
|
get slideInterval(): number {
|
||||||
@ -36,5 +41,14 @@ export class SettingsService {
|
|||||||
|
|
||||||
set slideInterval(interval: number) {
|
set slideInterval(interval: number) {
|
||||||
localStorage.setItem(SLIDE_INTERVAL_KEY, JSON.stringify(interval));
|
localStorage.setItem(SLIDE_INTERVAL_KEY, JSON.stringify(interval));
|
||||||
|
this.intervalSubject.next(interval);
|
||||||
|
}
|
||||||
|
|
||||||
|
get slideIntervalChanged(): Observable<number> {
|
||||||
|
return this.intervalSubject.asObservable();
|
||||||
|
}
|
||||||
|
|
||||||
|
get teamChanged(): Observable<Team> {
|
||||||
|
return this.teamSubject.asObservable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
15
src/app/shared/service/timer.service.spec.ts
Normal file
15
src/app/shared/service/timer.service.spec.ts
Normal file
@ -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();
|
||||||
|
}));
|
||||||
|
});
|
||||||
62
src/app/shared/service/timer.service.ts
Normal file
62
src/app/shared/service/timer.service.ts
Normal file
@ -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<number> = new Subject<number>();
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -17,27 +17,26 @@ export const slideInOutAnimation =
|
|||||||
|
|
||||||
// route 'enter' transition
|
// route 'enter' transition
|
||||||
transition(':enter', [
|
transition(':enter', [
|
||||||
|
|
||||||
// styles at start of transition
|
// styles at start of transition
|
||||||
style({
|
style({
|
||||||
// start with the content positioned off the right of the screen,
|
// 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
|
// -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
|
// 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
|
// transition the right position to 0 which slides the content into view
|
||||||
right: 0
|
transform: 'translateX(0)'
|
||||||
}))
|
}))
|
||||||
]),
|
]),
|
||||||
|
|
||||||
// route 'leave' transition
|
// route 'leave' transition
|
||||||
transition(':leave', [
|
transition(':leave', [
|
||||||
// animation and styles at end of transition
|
// 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
|
// transition the right position to -400% which slides the content out of view
|
||||||
right: '-400%'
|
transform: 'translateX(-100%)'
|
||||||
}))
|
}))
|
||||||
])
|
])
|
||||||
]);
|
]);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user