diff --git a/src/app/admin/slide-list/slide-list.component.html b/src/app/admin/slide-list/slide-list.component.html
index 8953079..2694ef6 100644
--- a/src/app/admin/slide-list/slide-list.component.html
+++ b/src/app/admin/slide-list/slide-list.component.html
@@ -16,10 +16,16 @@
|
+
+
+ class="large link red fitted trash alternate outline icon">
|
{{slide.title}} |
{{slideTeam(slide.team)}} |
diff --git a/src/app/admin/slide-list/slide-list.component.ts b/src/app/admin/slide-list/slide-list.component.ts
index 489a00d..418ad8b 100644
--- a/src/app/admin/slide-list/slide-list.component.ts
+++ b/src/app/admin/slide-list/slide-list.component.ts
@@ -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,
diff --git a/src/app/display/display.module.ts b/src/app/display/display.module.ts
index 8d68310..bbd8895 100644
--- a/src/app/display/display.module.ts
+++ b/src/app/display/display.module.ts
@@ -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 { }
diff --git a/src/app/display/slide-show.service.spec.ts b/src/app/display/slide-show.service.spec.ts
new file mode 100644
index 0000000..7820080
--- /dev/null
+++ b/src/app/display/slide-show.service.spec.ts
@@ -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();
+ }));
+});
diff --git a/src/app/display/slide-show.service.ts b/src/app/display/slide-show.service.ts
new file mode 100644
index 0000000..24dfe15
--- /dev/null
+++ b/src/app/display/slide-show.service.ts
@@ -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 = [];
+
+ 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
+ )
+ );
+ }
+
+}
diff --git a/src/app/display/slide/slide.component.css b/src/app/display/slide/slide.component.css
index 3703d02..333951d 100644
--- a/src/app/display/slide/slide.component.css
+++ b/src/app/display/slide/slide.component.css
@@ -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); }
\ No newline at end of file
diff --git a/src/app/shared/service/slide.service.ts b/src/app/shared/service/slide.service.ts
index c89551e..e5b8ffa 100644
--- a/src/app/shared/service/slide.service.ts
+++ b/src/app/shared/service/slide.service.ts
@@ -10,15 +10,18 @@ import { Slide } from '../slide';
export class SlideService implements Resolve>{
private apiEndPoint = environment.apiUrl + '/api/slide';
+ private apiEndPointPosition = environment.apiUrl + '/api/slide-position';
private cachedSlides: Array = [];
constructor(private httpClient: HttpClient) {}
private static prepareSlideData(slide: Slide) {
const slideToSave = Object.assign({}, slide);
- slideToSave.team = slideToSave.team.id === null
- ? null
- : slideToSave.team.id;
+ try {
+ slideToSave.team = slideToSave.team.id === null
+ ? null
+ : slideToSave.team.id;
+ } catch (e) {}
return slideToSave;
}
@@ -36,6 +39,14 @@ export class SlideService implements Resolve>{
: this.update(slide);
}
+ public moveUp(slide: Slide): Observable> {
+ return this.changePosition(slide, slide.position - 1);
+ }
+
+ public moveDown(slide: Slide): Observable> {
+ return this.changePosition(slide, slide.position + 1);
+ }
+
public create(slide: Slide): Observable {
return this.httpClient.post(this.apiEndPoint, SlideService.prepareSlideData(slide));
}
@@ -44,6 +55,12 @@ export class SlideService implements Resolve>{
return this.httpClient.put(`${this.apiEndPoint}/${slide.id.toString()}`, SlideService.prepareSlideData(slide));
}
+ public changePosition(slide: Slide, position: number): Observable> {
+ return this.httpClient.put>(`${this.apiEndPointPosition}/${slide.id.toString()}`, {
+ position: position
+ });
+ }
+
public delete(slide: Slide): Observable {
return this.httpClient.delete(`${this.apiEndPoint}/${slide.id.toString()}`);
}
diff --git a/src/app/shared/slide.ts b/src/app/shared/slide.ts
index 0b74dd1..095bcad 100644
--- a/src/app/shared/slide.ts
+++ b/src/app/shared/slide.ts
@@ -8,4 +8,5 @@ export class Slide {
isVisible = true;
createdAt: String = null;
updatedAt: String = null;
+ position = 0;
}