Skip to content

Commit a052bf5

Browse files
committed
Polish previews
1 parent 3b2db3a commit a052bf5

17 files changed

+151
-102
lines changed

apps/codelab/src/app/admin/content/presentation-editor/content.component.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,14 @@ export class ContentComponent {
2323
})
2424
);
2525

26-
currentSlideIndex$ = this.contentService.currentSlideIndex$;
26+
currentSlideIndex$ = this.navigationService.currentSlideIndex$;
2727

2828
currentSlide$ = combineLatest([
2929
this.navigationService.currentSlideIndex$,
3030
this.presentation$
3131
]).pipe(
32-
map(([slide, presentation]) => {
33-
return presentation.slides[slide || 0];
32+
map(([slideIndex, presentation]) => {
33+
return presentation.slides[slideIndex || 0];
3434
})
3535
);
3636

apps/codelab/src/app/admin/content/presentation-editor/preview/preview.module.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { FormsModule } from '@angular/forms';
1515
BlankComponent,
1616
],
1717
exports: [PreviewComponent, SlidePreviewComponent, DynamicRendererComponent],
18-
imports: [CommonModule, NgxdModule, FormsModule],
18+
imports: [CommonModule, NgxdModule, FormsModule,],
1919
})
20-
export class PreviewModule {}
20+
export class PreviewModule {
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
:host {
2+
display: block;
3+
width: 200px;
4+
position: relative;
5+
padding: 4px;
6+
7+
}
8+
9+
:host-context(.small) :host {
10+
width: 100px;
11+
}
12+
13+
:host-context(.small) slides-slide-preview {
14+
width: 500px;
15+
height: 410px;
16+
}
17+
18+
:host-context(.medium) {
19+
width: 208px;
20+
height: 150px;
21+
overflow: hidden;
22+
}
23+
24+
:host-context(.medium) slides-slide-preview {
25+
width: 1050px;
26+
height: 780px;
27+
}
28+
29+
slides-slide-preview {
30+
display: block;
31+
transform: scale(0.2);
32+
position: absolute;
33+
transform-origin: 0 0;
34+
width: 500px;
35+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<slides-slide-preview [slide]="slide" [mode]="mode"></slides-slide-preview>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { ComponentFixture, TestBed } from '@angular/core/testing';
2+
3+
import { SmallSlidePreviewComponent } from './small-slide-preview.component';
4+
5+
describe('SmallSlidePreviewComponent', () => {
6+
let component: SmallSlidePreviewComponent;
7+
let fixture: ComponentFixture<SmallSlidePreviewComponent>;
8+
9+
beforeEach(async () => {
10+
await TestBed.configureTestingModule({
11+
declarations: [ SmallSlidePreviewComponent ]
12+
})
13+
.compileComponents();
14+
15+
fixture = TestBed.createComponent(SmallSlidePreviewComponent);
16+
component = fixture.componentInstance;
17+
fixture.detectChanges();
18+
});
19+
20+
it('should create', () => {
21+
expect(component).toBeTruthy();
22+
});
23+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { Component, Input } from '@angular/core';
2+
import { ContentSlide, SlideViewType } from "../../../../types";
3+
import { PreviewModule } from "../../../preview.module";
4+
5+
@Component({
6+
selector: 'slides-small-slide-preview',
7+
templateUrl: './small-slide-preview.component.html',
8+
styleUrls: ['./small-slide-preview.component.css'],
9+
standalone: true,
10+
imports: [PreviewModule]
11+
})
12+
export class SmallSlidePreviewComponent {
13+
@Input() slide!: ContentSlide;
14+
@Input() mode: SlideViewType = 'preview';
15+
}

apps/codelab/src/app/admin/content/presentation-editor/services/content.service.ts

Lines changed: 24 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,18 @@
11
import { Injectable, OnDestroy } from '@angular/core';
22
import { AngularFirestore } from '@angular/fire/compat/firestore';
3-
import { ActivatedRoute, Router } from '@angular/router';
4-
import { BehaviorSubject, merge, Subject } from 'rxjs';
5-
import {
6-
auditTime,
7-
distinctUntilChanged,
8-
map,
9-
scan,
10-
shareReplay,
11-
takeUntil,
12-
tap,
13-
} from 'rxjs/operators';
3+
import { merge, Subject } from 'rxjs';
4+
import { auditTime, distinctUntilChanged, map, scan, shareReplay, take, takeUntil, } from 'rxjs/operators';
145
import { nanoid } from 'nanoid';
156
import { ContentBlock, ContentPresentation } from '../types';
167
import { reducer } from '../reducer';
178
import { serverTimestamp } from '@angular/fire/database';
9+
import { NavigationService } from "./navigation.service";
1810

1911
const DOC_KEY = 'presentations';
2012

21-
@Injectable({ providedIn: 'root' })
13+
@Injectable({providedIn: 'root'})
2214
export class ContentService implements OnDestroy {
23-
private readonly currentSlideSubject = new BehaviorSubject(0);
24-
25-
public readonly currentSlideIndex$ = this.currentSlideSubject;
15+
public readonly currentSlideIndex$ = this.navigationService.currentSlideIndex$;
2616

2717
private readonly presentations = this.firestore.collection('presentations');
2818
private readonly presentations$ = this.presentations
@@ -63,16 +53,15 @@ export class ContentService implements OnDestroy {
6353
);
6454

6555
constructor(
66-
readonly firestore: AngularFirestore,
67-
readonly route: ActivatedRoute,
68-
readonly router: Router
56+
private readonly firestore: AngularFirestore,
57+
private readonly navigationService: NavigationService
6958
) {
7059
// TODO: There should be a better way
71-
// this.goToSlide(router.routerState.snapshot.root.firstChild.firstChild.params.id || 0);
60+
7261
this.state$
7362
.pipe(auditTime(2000), takeUntil(this.onDestroy$))
7463
.subscribe((presentations) => {
75-
this.presentations.doc('presentations').set({ presentations });
64+
this.presentations.doc('presentations').set({presentations});
7665
});
7766
}
7867

@@ -99,19 +88,21 @@ export class ContentService implements OnDestroy {
9988
}
10089

10190
addSlide(presentationId: string) {
102-
const index = this.currentSlideIndex$.value;
103-
const action = {
104-
type: 'addSlide',
105-
payload: {
106-
slide: {
107-
id: this.uniqueId(),
108-
title: 'New slide',
109-
blocks: [],
91+
this.currentSlideIndex$.pipe(take(1)).subscribe(index => {
92+
const action = {
93+
type: 'addSlide',
94+
payload: {
95+
slide: {
96+
id: this.uniqueId(),
97+
title: 'New slide',
98+
blocks: [],
99+
},
100+
index,
110101
},
111-
index,
112-
},
113-
};
114-
this.dispatch(presentationId, action);
102+
};
103+
this.dispatch(presentationId, action);
104+
});
105+
115106
}
116107

117108
updateSlideMeta(
@@ -247,7 +238,7 @@ export class ContentService implements OnDestroy {
247238
deletePresentation(presentationId: string) {
248239
const action = {
249240
type: 'deletePresentation',
250-
payload: { presentationId },
241+
payload: {presentationId},
251242
};
252243

253244
this.dispatch(presentationId, action);

apps/codelab/src/app/admin/content/presentation-editor/side-panel/side-panel.component.html

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<div class="slides-wrapper" tabindex="0">
1+
<mat-selection-list (selectionChange)="handleSelectionChange($event)" class="slides-wrapper" tabindex="0">
22
<button (click)="addSlide()">Add</button>
33

44
<div
@@ -23,19 +23,22 @@
2323
role="button"
2424
>
2525
<div *cdkDragPreview>
26-
<div *ngFor="let selectedItem of selectionModel.selected"></div>
26+
<div *ngFor="let selectedItem of selectionModel.selected">
27+
{{selectedItem}}!
28+
</div>
2729
</div>
2830
<div *cdkDragPlaceholder>
2931
<div class="drag-placeholder"></div>
3032
</div>
3133

3234
<div class="slide">
33-
<slides-slide-preview
35+
<slides-small-slide-preview
36+
class="small"
3437
inert
3538
[slide]="slide"
3639
mode="preview"
37-
></slides-slide-preview>
40+
></slides-small-slide-preview>
3841
</div>
3942
</div>
4043
</div>
41-
</div>
44+
</mat-selection-list>

apps/codelab/src/app/admin/content/presentation-editor/side-panel/side-panel.component.scss

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,6 @@
6464
pointer-events: none;
6565
text-decoration: none;
6666
color: inherit;
67-
68-
slides-slide-preview {
69-
zoom: 0.2;
70-
}
7167
}
7268

7369
.dragging {

apps/codelab/src/app/admin/content/presentation-editor/side-panel/side-panel.component.ts

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,4 @@
1-
import {
2-
Component,
3-
ElementRef,
4-
HostListener,
5-
Input,
6-
OnChanges,
7-
OnInit,
8-
Output,
9-
SimpleChanges
10-
} from '@angular/core';
1+
import { Component, ElementRef, HostListener, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core';
112
import { Location } from '@angular/common';
123
import { CdkDragDrop, CdkDragStart, DragRef } from '@angular/cdk/drag-drop';
134
import { ActivatedRoute, Router } from '@angular/router';
@@ -17,10 +8,8 @@ import { NavigationService } from '../services/navigation.service';
178
import { ContentSlide } from '../types';
189

1910
import { MultiselectModel } from '../../../../multiselect/multiselect-model';
20-
import {
21-
isFromContext,
22-
KeyboardEventWithTarget
23-
} from '../../../../shared/helpers/helpers';
11+
import { isFromContext, KeyboardEventWithTarget } from '../../../../shared/helpers/helpers';
12+
import { MatSelectionListChange } from "@angular/material/list";
2413

2514
function slideIdsMapper(slides: ContentSlide[]): string[] {
2615
return slides.map(slide => slide.id);
@@ -40,13 +29,14 @@ export class SidePanelComponent implements OnInit, OnChanges {
4029
public selectionModel: MultiselectModel<string> = new MultiselectModel();
4130

4231
constructor(
43-
readonly el: ElementRef,
44-
readonly location: Location,
45-
readonly route: ActivatedRoute,
46-
readonly router: Router,
47-
readonly contentService: ContentService,
48-
readonly navigationService: NavigationService
49-
) {}
32+
private readonly el: ElementRef,
33+
private readonly location: Location,
34+
private readonly route: ActivatedRoute,
35+
private readonly router: Router,
36+
private readonly contentService: ContentService,
37+
private readonly navigationService: NavigationService
38+
) {
39+
}
5040

5141
ngOnInit() {
5242
this.resetSelected();
@@ -58,6 +48,12 @@ export class SidePanelComponent implements OnInit, OnChanges {
5848

5949
this.selectionModel.setItems(slideIds);
6050
}
51+
52+
console.log(this.currentSlideIndex, '--');
53+
54+
if (changes.currentSlideIndex) {
55+
console.log(this.currentSlideIndex);
56+
}
6157
}
6258

6359
trackBySlideId(index: number, slide: ContentSlide) {
@@ -70,9 +66,8 @@ export class SidePanelComponent implements OnInit, OnChanges {
7066

7167
@HostListener('document:keydown.arrowdown', ['$event'])
7268
nextSlide(event: KeyboardEventWithTarget<HTMLElement>) {
73-
if (this.isFromSidePanelContext(event.target)) {
69+
if (this.isFromSidePanelContext(event.target) && this.currentSlideIndex + 1 < this.slides.length) {
7470
this.navigationService.nextSlide(this.presentationId);
75-
7671
event.preventDefault();
7772
}
7873
}
@@ -170,4 +165,8 @@ export class SidePanelComponent implements OnInit, OnChanges {
170165
this.navigationService.goToSlide(this.presentationId, index);
171166
}
172167
}
168+
169+
handleSelectionChange($event: MatSelectionListChange) {
170+
debugger;
171+
}
173172
}

0 commit comments

Comments
 (0)