* slide position change implemented

* slide css changed to work with [innerHTML]
* slideshow service basics
This commit is contained in:
Dávid Danyi 2018-04-17 17:20:39 +02:00
parent 24cbc3454d
commit 90ddebf46b
8 changed files with 200 additions and 93 deletions

View File

@ -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>

View File

@ -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,

View File

@ -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 { }

View 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();
}));
});

View 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
)
);
}
}

View File

@ -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); }

View File

@ -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()}`);
}

View File

@ -8,4 +8,5 @@ export class Slide {
isVisible = true;
createdAt: String = null;
updatedAt: String = null;
position = 0;
}