* slide position change implemented
* slide css changed to work with [innerHTML] * slideshow service basics
This commit is contained in:
parent
24cbc3454d
commit
90ddebf46b
@ -16,10 +16,16 @@
|
||||
<tbody>
|
||||
<tr *ngFor="let slide of slides">
|
||||
<td class="collapsing">
|
||||
<a title="Up" (click)="moveUp(slide)"><i
|
||||
class="large link arrow alternate circle up outline icon"
|
||||
[ngClass]="upClass(slide)"></i></a>
|
||||
<a title="Down" (click)="moveDown(slide)"><i
|
||||
class="large link arrow alternate circle down outline icon"
|
||||
[ngClass]="downClass(slide)"></i></a>
|
||||
<a [routerLink]="['/admin/slide/edit', slide.id]" title="Change"><i
|
||||
class="large pencil alternate icon"></i></a>
|
||||
<a title="Delete" (click)="delete(slide)"><i
|
||||
class="large red fitted trash alternate outline icon"></i></a>
|
||||
class="large link red fitted trash alternate outline icon"></i></a>
|
||||
</td>
|
||||
<td>{{slide.title}}</td>
|
||||
<td class="collapsing">{{slideTeam(slide.team)}}</td>
|
||||
|
||||
@ -35,6 +35,34 @@ export class SlideListComponent implements OnInit {
|
||||
return team === null ? 'All teams' : team.name;
|
||||
}
|
||||
|
||||
public moveUp(slide: Slide) {
|
||||
if (!this.isFirstSlide(slide)) {
|
||||
this.slideService.moveUp(slide).subscribe(slides => this.slides = slides);
|
||||
}
|
||||
}
|
||||
|
||||
public moveDown(slide: Slide) {
|
||||
if (!this.isLastSlide(slide)) {
|
||||
this.slideService.moveDown(slide).subscribe(slides => this.slides = slides);
|
||||
}
|
||||
}
|
||||
|
||||
public upClass(slide: Slide) {
|
||||
const first = this.isFirstSlide(slide);
|
||||
return {
|
||||
'blue link': !first,
|
||||
'inverted grey': first,
|
||||
};
|
||||
}
|
||||
|
||||
public downClass(slide: Slide) {
|
||||
const last = this.isLastSlide(slide);
|
||||
return {
|
||||
'blue link': !last,
|
||||
'inverted grey': last,
|
||||
};
|
||||
}
|
||||
|
||||
public delete(slide: Slide) {
|
||||
if (confirm(`Are you sure you want to delete the slide '${slide.title}'`)) {
|
||||
this.slideService.delete(slide).subscribe(result => {
|
||||
@ -45,6 +73,14 @@ export class SlideListComponent implements OnInit {
|
||||
}
|
||||
}
|
||||
|
||||
public isFirstSlide(slide: Slide) {
|
||||
return slide.position === 0;
|
||||
}
|
||||
|
||||
public isLastSlide(slide: Slide) {
|
||||
return slide.position === this.slides.length - 1;
|
||||
}
|
||||
|
||||
public visibleClass(slide: Slide) {
|
||||
return {
|
||||
'green check': slide.isVisible,
|
||||
|
||||
@ -8,6 +8,7 @@ import { SettingsComponent } from './settings/settings.component';
|
||||
import { SuiModule } from 'ng2-semantic-ui';
|
||||
import { SlideComponent } from './slide/slide.component';
|
||||
import { SlideShowComponent } from './slide-show/slide-show.component';
|
||||
import { SlideShowService } from './slide-show.service';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
@ -17,6 +18,7 @@ import { SlideShowComponent } from './slide-show/slide-show.component';
|
||||
DisplayRoutingModule
|
||||
],
|
||||
exports: [SlideComponent],
|
||||
declarations: [CommitTrackerComponent, SettingsComponent, SlideComponent, SlideShowComponent]
|
||||
declarations: [CommitTrackerComponent, SettingsComponent, SlideComponent, SlideShowComponent],
|
||||
providers: [SlideShowService]
|
||||
})
|
||||
export class DisplayModule { }
|
||||
|
||||
15
src/app/display/slide-show.service.spec.ts
Normal file
15
src/app/display/slide-show.service.spec.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import { TestBed, inject } from '@angular/core/testing';
|
||||
|
||||
import { SlideShowService } from './slide-show.service';
|
||||
|
||||
describe('SlideShowService', () => {
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
providers: [SlideShowService]
|
||||
});
|
||||
});
|
||||
|
||||
it('should be created', inject([SlideShowService], (service: SlideShowService) => {
|
||||
expect(service).toBeTruthy();
|
||||
}));
|
||||
});
|
||||
40
src/app/display/slide-show.service.ts
Normal file
40
src/app/display/slide-show.service.ts
Normal file
@ -0,0 +1,40 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Slide } from '../shared/slide';
|
||||
import { SlideService } from '../shared/service/slide.service';
|
||||
import { Router } from '@angular/router';
|
||||
import { SettingsService } from '../shared/service/settings.service';
|
||||
|
||||
@Injectable()
|
||||
export class SlideShowService {
|
||||
|
||||
private currentSlideIndex = 0;
|
||||
private slides: Array<Slide> = [];
|
||||
|
||||
constructor(private slideService: SlideService,
|
||||
private settingsService: SettingsService,
|
||||
private router: Router) {
|
||||
}
|
||||
|
||||
public init() {
|
||||
this.router.navigate(['/commit-tracker']);
|
||||
}
|
||||
|
||||
public nextSlide() {
|
||||
if (this.currentSlideIndex === this.slides.length - 1) {
|
||||
this.router.navigate(['/commit-tracker']);
|
||||
} else {
|
||||
this.currentSlideIndex++;
|
||||
this.router.navigate(['/slideshow', this.slides[this.currentSlideIndex]]);
|
||||
}
|
||||
}
|
||||
|
||||
private reloadSlides() {
|
||||
const team = this.settingsService.team;
|
||||
this.slideService.list().subscribe(
|
||||
slides => this.slides = slides.filter(
|
||||
slide => slide.team.id === team.id
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@ -9,100 +9,96 @@
|
||||
font-family: "Source Sans Pro", Helvetica, sans-serif;
|
||||
font-size: 42px;
|
||||
font-weight: normal;
|
||||
color: #fff; }
|
||||
|
||||
section {
|
||||
line-height: 1.3;
|
||||
font-weight: inherit; }
|
||||
color: #fff;
|
||||
padding: 4rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/*********************************************
|
||||
* HEADERS
|
||||
*********************************************/
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
:host ::ng-deep h1,
|
||||
:host ::ng-deep h2,
|
||||
:host ::ng-deep h3,
|
||||
:host ::ng-deep h4,
|
||||
:host ::ng-deep h5,
|
||||
:host ::ng-deep h6 {
|
||||
margin: 0 0 20px 0;
|
||||
color: #fff;
|
||||
font-family: "Source Sans Pro", Helvetica, sans-serif;
|
||||
font-weight: 600;
|
||||
line-height: 1.2;
|
||||
line-height: 1.2 !important;
|
||||
letter-spacing: normal;
|
||||
text-transform: uppercase;
|
||||
text-shadow: none;
|
||||
word-wrap: break-word; }
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2.5em; }
|
||||
|
||||
h2 {
|
||||
font-size: 1.6em; }
|
||||
|
||||
h3 {
|
||||
font-size: 1.3em; }
|
||||
|
||||
h4 {
|
||||
font-size: 1em; }
|
||||
|
||||
h1 {
|
||||
text-shadow: none; }
|
||||
:host ::ng-deep h1 {
|
||||
font-size: 2.5em !important;
|
||||
text-shadow: none !important;
|
||||
}
|
||||
:host ::ng-deep h2 {font-size: 1.6em !important;}
|
||||
:host ::ng-deep h3 {font-size: 1.3em !important;}
|
||||
:host ::ng-deep h4 {font-size: 1em !important;}
|
||||
|
||||
/*********************************************
|
||||
* OTHER
|
||||
*********************************************/
|
||||
p {
|
||||
:host ::ng-deep p {
|
||||
margin: 20px 0;
|
||||
line-height: 1.3; }
|
||||
line-height: 1.3 !important; }
|
||||
|
||||
/* Ensure certain elements are never larger than the slide itself */
|
||||
img,
|
||||
video,
|
||||
iframe {
|
||||
:host ::ng-deep img,
|
||||
:host ::ng-deep video,
|
||||
:host ::ng-deep iframe {
|
||||
max-width: 95%;
|
||||
max-height: 95%; }
|
||||
|
||||
strong,
|
||||
b {
|
||||
:host ::ng-deep strong,
|
||||
:host ::ng-deep b {
|
||||
font-weight: bold; }
|
||||
|
||||
em {
|
||||
:host ::ng-deep em {
|
||||
font-style: italic; }
|
||||
|
||||
ol,
|
||||
dl,
|
||||
ul {
|
||||
:host ::ng-deep ol,
|
||||
:host ::ng-deep dl,
|
||||
:host ::ng-deep ul {
|
||||
display: inline-block;
|
||||
text-align: left;
|
||||
margin: 0 0 0 1em; }
|
||||
|
||||
ol {
|
||||
:host ::ng-deep ol {
|
||||
list-style-type: decimal; }
|
||||
|
||||
ul {
|
||||
:host ::ng-deep ul {
|
||||
list-style-type: disc; }
|
||||
|
||||
ul ul {
|
||||
:host ::ng-deep li {
|
||||
line-height: 1.1; }
|
||||
|
||||
:host ::ng-deep ul ul {
|
||||
list-style-type: square; }
|
||||
|
||||
ul ul ul {
|
||||
:host ::ng-deep ul ul ul {
|
||||
list-style-type: circle; }
|
||||
|
||||
ul ul,
|
||||
ul ol,
|
||||
ol ol,
|
||||
ol ul {
|
||||
:host ::ng-deep ul ul,
|
||||
:host ::ng-deep ul ol,
|
||||
:host ::ng-deep ol ol,
|
||||
:host ::ng-deep ol ul {
|
||||
display: block;
|
||||
margin-left: 40px; }
|
||||
margin-left: 10px; }
|
||||
|
||||
dt {
|
||||
:host ::ng-deep dt {
|
||||
font-weight: bold; }
|
||||
|
||||
dd {
|
||||
:host ::ng-deep dd {
|
||||
margin-left: 40px; }
|
||||
|
||||
blockquote {
|
||||
:host ::ng-deep blockquote {
|
||||
display: block;
|
||||
position: relative;
|
||||
width: 70%;
|
||||
@ -110,16 +106,16 @@ blockquote {
|
||||
padding: 5px;
|
||||
font-style: italic;
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2); }
|
||||
box-shadow: 0 0 2px rgba(0, 0, 0, 0.2); }
|
||||
|
||||
blockquote p:first-child,
|
||||
blockquote p:last-child {
|
||||
:host ::ng-deep blockquote p:first-child,
|
||||
:host ::ng-deep blockquote p:last-child {
|
||||
display: inline-block; }
|
||||
|
||||
q {
|
||||
:host ::ng-deep q {
|
||||
font-style: italic; }
|
||||
|
||||
pre {
|
||||
:host ::ng-deep pre {
|
||||
display: block;
|
||||
position: relative;
|
||||
width: 90%;
|
||||
@ -129,116 +125,110 @@ pre {
|
||||
font-family: monospace;
|
||||
line-height: 1.2em;
|
||||
word-wrap: break-word;
|
||||
box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.3); }
|
||||
box-shadow: 0 0 6px rgba(0, 0, 0, 0.3); }
|
||||
|
||||
code {
|
||||
:host ::ng-deep code {
|
||||
font-family: monospace;
|
||||
text-transform: none; }
|
||||
|
||||
pre code {
|
||||
:host ::ng-deep pre code {
|
||||
display: block;
|
||||
padding: 5px;
|
||||
overflow: auto;
|
||||
max-height: 400px;
|
||||
word-wrap: normal; }
|
||||
|
||||
table {
|
||||
:host ::ng-deep table {
|
||||
margin: auto;
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0; }
|
||||
|
||||
table th {
|
||||
:host ::ng-deep table th {
|
||||
font-weight: bold; }
|
||||
|
||||
table th,
|
||||
table td {
|
||||
:host ::ng-deep table th,
|
||||
:host ::ng-deep table td {
|
||||
text-align: left;
|
||||
padding: 0.2em 0.5em 0.2em 0.5em;
|
||||
border-bottom: 1px solid; }
|
||||
|
||||
table th[align="center"],
|
||||
table td[align="center"] {
|
||||
:host ::ng-deep table th[align="center"],
|
||||
:host ::ng-deep table td[align="center"] {
|
||||
text-align: center; }
|
||||
|
||||
table th[align="right"],
|
||||
table td[align="right"] {
|
||||
:host ::ng-deep table th[align="right"],
|
||||
:host ::ng-deep table td[align="right"] {
|
||||
text-align: right; }
|
||||
|
||||
table tbody tr:last-child th,
|
||||
table tbody tr:last-child td {
|
||||
:host ::ng-deep table tbody tr:last-child th,
|
||||
:host ::ng-deep table tbody tr:last-child td {
|
||||
border-bottom: none; }
|
||||
|
||||
sup {
|
||||
:host ::ng-deep sup {
|
||||
vertical-align: super; }
|
||||
|
||||
sub {
|
||||
:host ::ng-deep sub {
|
||||
vertical-align: sub; }
|
||||
|
||||
small {
|
||||
:host ::ng-deep small {
|
||||
display: inline-block;
|
||||
font-size: 0.6em;
|
||||
line-height: 1.2em;
|
||||
vertical-align: top; }
|
||||
|
||||
small * {
|
||||
:host ::ng-deep small * {
|
||||
vertical-align: top; }
|
||||
|
||||
/*********************************************
|
||||
* LINKS
|
||||
*********************************************/
|
||||
a {
|
||||
:host ::ng-deep a {
|
||||
color: #42affa;
|
||||
text-decoration: none;
|
||||
-webkit-transition: color .15s ease;
|
||||
-moz-transition: color .15s ease;
|
||||
transition: color .15s ease; }
|
||||
|
||||
a:hover {
|
||||
:host ::ng-deep a:hover {
|
||||
color: #8dcffc;
|
||||
text-shadow: none;
|
||||
border: none; }
|
||||
|
||||
.roll span:after {
|
||||
:host ::ng-deep .roll span:after {
|
||||
color: #fff;
|
||||
background: #068de9; }
|
||||
|
||||
/*********************************************
|
||||
* IMAGES
|
||||
*********************************************/
|
||||
section img {
|
||||
margin: 15px 0px;
|
||||
:host ::ng-deep section img {
|
||||
margin: 15px 0;
|
||||
background: rgba(255, 255, 255, 0.12);
|
||||
border: 4px solid #fff;
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); }
|
||||
|
||||
section img.plain {
|
||||
:host ::ng-deep section img.plain {
|
||||
border: 0;
|
||||
box-shadow: none; }
|
||||
|
||||
a img {
|
||||
:host ::ng-deep a img {
|
||||
-webkit-transition: all .15s linear;
|
||||
-moz-transition: all .15s linear;
|
||||
transition: all .15s linear; }
|
||||
|
||||
a:hover img {
|
||||
:host ::ng-deep a:hover img {
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
border-color: #42affa;
|
||||
box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); }
|
||||
|
||||
/*********************************************
|
||||
* NAVIGATION CONTROLS
|
||||
*********************************************/
|
||||
.controls {
|
||||
color: #42affa; }
|
||||
|
||||
/*********************************************
|
||||
* PROGRESS BAR
|
||||
*********************************************/
|
||||
.progress {
|
||||
:host ::ng-deep .progress {
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
color: #42affa; }
|
||||
|
||||
.progress span {
|
||||
:host ::ng-deep .progress span {
|
||||
-webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
|
||||
-moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
|
||||
transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
|
||||
@ -10,15 +10,18 @@ import { Slide } from '../slide';
|
||||
export class SlideService implements Resolve<Array<Slide>>{
|
||||
|
||||
private apiEndPoint = environment.apiUrl + '/api/slide';
|
||||
private apiEndPointPosition = environment.apiUrl + '/api/slide-position';
|
||||
private cachedSlides: Array<Slide> = [];
|
||||
|
||||
constructor(private httpClient: HttpClient) {}
|
||||
|
||||
private static prepareSlideData(slide: Slide) {
|
||||
const slideToSave = <any>Object.assign({}, slide);
|
||||
try {
|
||||
slideToSave.team = slideToSave.team.id === null
|
||||
? null
|
||||
: slideToSave.team.id;
|
||||
} catch (e) {}
|
||||
return slideToSave;
|
||||
}
|
||||
|
||||
@ -36,6 +39,14 @@ export class SlideService implements Resolve<Array<Slide>>{
|
||||
: this.update(slide);
|
||||
}
|
||||
|
||||
public moveUp(slide: Slide): Observable<Array<Slide>> {
|
||||
return this.changePosition(slide, slide.position - 1);
|
||||
}
|
||||
|
||||
public moveDown(slide: Slide): Observable<Array<Slide>> {
|
||||
return this.changePosition(slide, slide.position + 1);
|
||||
}
|
||||
|
||||
public create(slide: Slide): Observable<Slide> {
|
||||
return this.httpClient.post<Slide>(this.apiEndPoint, SlideService.prepareSlideData(slide));
|
||||
}
|
||||
@ -44,6 +55,12 @@ export class SlideService implements Resolve<Array<Slide>>{
|
||||
return this.httpClient.put<Slide>(`${this.apiEndPoint}/${slide.id.toString()}`, SlideService.prepareSlideData(slide));
|
||||
}
|
||||
|
||||
public changePosition(slide: Slide, position: number): Observable<Array<Slide>> {
|
||||
return this.httpClient.put<Array<Slide>>(`${this.apiEndPointPosition}/${slide.id.toString()}`, {
|
||||
position: position
|
||||
});
|
||||
}
|
||||
|
||||
public delete(slide: Slide): Observable<boolean> {
|
||||
return this.httpClient.delete<boolean>(`${this.apiEndPoint}/${slide.id.toString()}`);
|
||||
}
|
||||
|
||||
@ -8,4 +8,5 @@ export class Slide {
|
||||
isVisible = true;
|
||||
createdAt: String = null;
|
||||
updatedAt: String = null;
|
||||
position = 0;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user