Skip to content
This repository was archived by the owner on Feb 6, 2024. It is now read-only.

Commit 96134d1

Browse files
merge(#91): save and load deck style/attributes
2 parents 6517ec7 + 52d45fe commit 96134d1

File tree

7 files changed

+138
-39
lines changed

7 files changed

+138
-39
lines changed

studio/src/app/components/editor/app-editor-toolbar/app-editor-toolbar.tsx

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ export class AppEditorToolbar {
3939
@Event() private slideDelete: EventEmitter<HTMLElement>;
4040

4141
@Event() private slideDidChange: EventEmitter<HTMLElement>;
42+
@Event() private deckDidChange: EventEmitter<HTMLElement>;
4243

4344
private subscription: Subscription;
4445
private deckBusyService: DeckBusyService;
@@ -425,7 +426,7 @@ export class AppEditorToolbar {
425426
this.selectedElement.style.color = $event.target.value;
426427
}
427428

428-
await this.emitSlideChange();
429+
await this.emitChange();
429430
};
430431

431432
// Background
@@ -490,7 +491,7 @@ export class AppEditorToolbar {
490491
this.selectedElement.style.background = $event.target.value;
491492
}
492493

493-
await this.emitSlideChange();
494+
await this.emitChange();
494495
};
495496

496497
private async openSlotType($event: UIEvent) {
@@ -542,21 +543,26 @@ export class AppEditorToolbar {
542543

543544
await this.initSelectedElement(element);
544545

545-
await this.emitSlideChange();
546+
await this.emitChange();
546547

547548
resolve();
548549
});
549550
}
550551

551-
private emitSlideChange(): Promise<void> {
552+
private emitChange(): Promise<void> {
552553
return new Promise<void>((resolve) => {
553554
if (!this.selectedElement || !this.selectedElement.parentElement) {
554555
resolve();
555556
return;
556557
}
557558

558-
// If not deck or slide, then parent is the container slide
559-
this.slideDidChange.emit(this.deckOrSlide ? this.selectedElement : this.selectedElement.parentElement);
559+
if (this.applyToAllDeck) {
560+
const deckElement: HTMLElement = this.deckOrSlide ? this.selectedElement.parentElement : this.selectedElement.parentElement.parentElement;
561+
this.deckDidChange.emit(deckElement);
562+
} else {
563+
// If not deck or slide, then parent is the container slide
564+
this.slideDidChange.emit(this.deckOrSlide ? this.selectedElement : this.selectedElement.parentElement);
565+
}
560566

561567
resolve();
562568
});

studio/src/app/handlers/editor/deck-events/deck-events.handler.tsx

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import {debounceTime, filter, take} from 'rxjs/operators';
33

44
import {Slide, SlideAttributes, SlideTemplate} from '../../../models/slide';
55
import {User} from '../../../models/user';
6-
import {Deck} from '../../../models/deck';
6+
import {Deck, DeckAttributes} from '../../../models/deck';
77

88
import {Utils} from '../../../utils/core/utils';
99

@@ -48,6 +48,7 @@ export class DeckEventsHandler {
4848
this.el = el;
4949

5050
this.el.addEventListener('input', this.onSlideInputChange, false);
51+
this.el.addEventListener('deckDidChange', this.onDeckChange, false);
5152
this.el.addEventListener('slideDidChange', this.onSlideChange, false);
5253
this.el.addEventListener('slideDidLoad', this.onSlideDidLoad, false);
5354
this.el.addEventListener('slideDelete', this.onSlideDelete, false);
@@ -59,6 +60,7 @@ export class DeckEventsHandler {
5960

6061
destroy() {
6162
this.el.removeEventListener('input', this.onSlideInputChange, true);
63+
this.el.removeEventListener('deckDidChange', this.onDeckChange, true);
6264
this.el.removeEventListener('slideDidChange', this.onSlideChange, true);
6365
this.el.removeEventListener('slideDidLoad', this.onSlideDidLoad, true);
6466
this.el.removeEventListener('slideDelete', this.onSlideDelete, true);
@@ -80,6 +82,14 @@ export class DeckEventsHandler {
8082
}
8183
};
8284

85+
private onDeckChange = async ($event: CustomEvent) => {
86+
if (!$event || !$event.detail) {
87+
return;
88+
}
89+
90+
await this.updateDeck($event.detail);
91+
};
92+
8393
private onSlideChange = async ($event: CustomEvent) => {
8494
if (!$event || !$event.detail) {
8595
return;
@@ -208,6 +218,43 @@ export class DeckEventsHandler {
208218
});
209219
}
210220

221+
private updateDeck(deck: HTMLElement): Promise<void> {
222+
return new Promise<void>(async (resolve) => {
223+
try {
224+
if (!deck) {
225+
resolve();
226+
return;
227+
}
228+
229+
this.deckBusyService.busy(true);
230+
231+
this.deckEditorService.watch().pipe(take(1)).subscribe(async (currentDeck: Deck) => {
232+
if (!currentDeck) {
233+
resolve();
234+
return;
235+
}
236+
237+
const attributes: DeckAttributes = await this.getDeckAttributes(deck);
238+
239+
if (attributes && Object.keys(attributes).length > 0) {
240+
currentDeck.attributes = attributes;
241+
}
242+
243+
const updatedDeck: Deck = await this.deckService.put(currentDeck);
244+
this.deckEditorService.next(updatedDeck);
245+
246+
this.deckBusyService.busy(false);
247+
248+
resolve();
249+
});
250+
} catch (err) {
251+
this.errorService.error(err);
252+
this.deckBusyService.busy(false);
253+
resolve();
254+
}
255+
});
256+
}
257+
211258
private updateSlide(slide: HTMLElement): Promise<void> {
212259
return new Promise<void>(async (resolve) => {
213260
try {
@@ -323,6 +370,18 @@ export class DeckEventsHandler {
323370
})
324371
}
325372

373+
private getDeckAttributes(deck: HTMLElement): Promise<DeckAttributes> {
374+
return new Promise<DeckAttributes>((resolve) => {
375+
let attributes: DeckAttributes = {};
376+
377+
if (deck.getAttribute('style')) {
378+
attributes.style = deck.getAttribute('style');
379+
}
380+
381+
resolve(attributes);
382+
})
383+
}
384+
326385
private cleanSlideContent(content: string): Promise<string> {
327386
return new Promise<string>((resolve) => {
328387
if (!content || content.length <= 0) {

studio/src/app/models/deck.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
1+
export interface DeckAttributes {
2+
style?: string;
3+
}
4+
15
export interface Deck {
26
id?: string;
37
slides: string[];
48
name: string;
59
owner_id: string;
10+
attributes?: DeckAttributes;
611
}

studio/src/app/pages/editor/app-editor/app-editor.tsx

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ import {CreateSlidesUtils} from '../../../utils/editor/create-slides.utils';
88

99
import {AuthUser} from '../../../models/auth-user';
1010
import {Slide, SlideTemplate} from '../../../models/slide';
11+
import {Deck} from '../../../models/deck';
12+
13+
import {ParseStyleUtils} from '../../../utils/editor/parse-style.utils';
1114

1215
import {DeckEventsHandler} from '../../../handlers/editor/deck-events/deck-events.handler';
1316

@@ -17,6 +20,7 @@ import {NavDirection, NavService} from '../../../services/nav/nav.service';
1720

1821
import {EditorHelper} from '../../../helpers/editor/editor.helper';
1922
import {DeckAction} from '../../../popovers/editor/app-deck-actions/deck-action';
23+
import {DeckEditorService} from '../../../services/deck/deck-editor.service';
2024

2125
interface FirstSlideContent {
2226
title: string;
@@ -51,10 +55,14 @@ export class AppEditor {
5155
private guestService: GuestService;
5256
private navService: NavService;
5357

58+
private deckEditorService: DeckEditorService;
59+
private deckStyle: any;
60+
5461
constructor() {
5562
this.authService = AuthService.getInstance();
5663
this.guestService = GuestService.getInstance();
5764
this.navService = NavService.getInstance();
65+
this.deckEditorService = DeckEditorService.getInstance();
5866
}
5967

6068
async componentWillLoad() {
@@ -153,10 +161,26 @@ export class AppEditor {
153161
this.slides = [...slides];
154162
}
155163

164+
await this.initDeckStyle();
165+
156166
resolve();
157167
});
158168
}
159169

170+
private initDeckStyle(): Promise<void> {
171+
return new Promise<void>((resolve) => {
172+
this.deckEditorService.watch().pipe(take(1)).subscribe(async (deck: Deck) => {
173+
if (deck && deck.attributes && deck.attributes.style) {
174+
this.deckStyle = await ParseStyleUtils.convertStyle(deck.attributes.style);
175+
} else {
176+
this.deckStyle = undefined;
177+
}
178+
179+
resolve();
180+
});
181+
});
182+
}
183+
160184
private concatSlide(extraSlide: any): Promise<void> {
161185
return new Promise<void>((resolve) => {
162186
this.slides = [...this.slides, extraSlide];
@@ -562,7 +586,7 @@ export class AppEditor {
562586
<app-navigation publish={true}></app-navigation>,
563587
<ion-content padding>
564588
<main class={this.displaying ? 'idle' : undefined}>
565-
<deckgo-deck embedded={true}
589+
<deckgo-deck embedded={true} style={this.deckStyle}
566590
onMouseDown={(e: MouseEvent) => this.deckTouched(e)}
567591
onTouchStart={(e: TouchEvent) => this.deckTouched(e)}
568592
onSlideNextDidChange={() => this.hideToolbar()}

studio/src/app/utils/editor/parse-slides.utils.tsx

Lines changed: 3 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import {Slide, SlideTemplate} from '../../models/slide';
2+
import {ParseStyleUtils} from './parse-style.utils';
23

34
export class ParseSlidesUtils {
45

@@ -36,7 +37,7 @@ export class ParseSlidesUtils {
3637

3738
const content = await this.parseElements(div, true);
3839

39-
const style = slide.attributes ? await this.convertStyle(slide.attributes.style) : undefined;
40+
const style = slide.attributes ? await ParseStyleUtils.convertStyle(slide.attributes.style) : undefined;
4041

4142
const src = slide.attributes && slide.attributes.src ? slide.attributes.src : undefined;
4243

@@ -86,7 +87,7 @@ export class ParseSlidesUtils {
8687

8788
const attributes: any = this.getAttributes(element);
8889
if (attributes.style) {
89-
attributes.style = await this.convertStyle(attributes.style);
90+
attributes.style = await ParseStyleUtils.convertStyle(attributes.style);
9091
}
9192

9293
if (attributes.slot) {
@@ -97,34 +98,6 @@ export class ParseSlidesUtils {
9798
});
9899
}
99100

100-
private static convertStyle(originalStyle: string): Promise<any> {
101-
return new Promise<any>((resolve) => {
102-
if (!originalStyle || originalStyle.length <= 0) {
103-
resolve(undefined);
104-
return;
105-
}
106-
107-
const result: any = {};
108-
109-
const styles: string[] = originalStyle.split(';');
110-
111-
if (styles && styles.length > 0) {
112-
styles.forEach((style: string) => {
113-
if (style && style.length > 0) {
114-
const split: string[] = style.split(':');
115-
if (split && split.length > 1) {
116-
result[split[0].trim()] = split[1].trim();
117-
} else if (split && split.length > 0) {
118-
result[split[0].trim()] = undefined;
119-
}
120-
}
121-
});
122-
}
123-
124-
resolve(result);
125-
});
126-
}
127-
128101
private static getAttributes(el): any {
129102
if (!el || !el.attributes) {
130103
return {};
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
export class ParseStyleUtils {
2+
3+
static convertStyle(originalStyle: string): Promise<any> {
4+
return new Promise<any>((resolve) => {
5+
if (!originalStyle || originalStyle.length <= 0) {
6+
resolve(undefined);
7+
return;
8+
}
9+
10+
const result: any = {};
11+
12+
const styles: string[] = originalStyle.split(';');
13+
14+
if (styles && styles.length > 0) {
15+
styles.forEach((style: string) => {
16+
if (style && style.length > 0) {
17+
const split: string[] = style.split(':');
18+
if (split && split.length > 1) {
19+
result[split[0].trim()] = split[1].trim();
20+
} else if (split && split.length > 0) {
21+
result[split[0].trim()] = undefined;
22+
}
23+
}
24+
});
25+
}
26+
27+
resolve(result);
28+
});
29+
}
30+
31+
}

studio/src/components.d.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88
import '@stencil/core';
99

1010
import '@ionic/core';
11+
import 'ionicons';
1112
import 'deckdeckgo';
1213
import 'deckdeckgo-inline-editor';
13-
import 'ionicons';
1414
import {
1515
EventEmitter,
1616
} from '@stencil/core';
@@ -77,6 +77,7 @@ export namespace Components {
7777
}
7878
interface AppEditorToolbarAttributes extends StencilHTMLAttributes {
7979
'onBlockSlide'?: (event: CustomEvent<boolean>) => void;
80+
'onDeckDidChange'?: (event: CustomEvent<HTMLElement>) => void;
8081
'onSlideDelete'?: (event: CustomEvent<HTMLElement>) => void;
8182
'onSlideDidChange'?: (event: CustomEvent<HTMLElement>) => void;
8283
}

0 commit comments

Comments
 (0)