From ce605a5c27e5d54166a9fb64b18f7e1b56c1f9c6 Mon Sep 17 00:00:00 2001 From: peterpeterparker Date: Sat, 4 Sep 2021 09:22:14 +0200 Subject: [PATCH 1/2] fix: slide navigation from aside menu --- .../actions/app-breadcrumbs/app-breadcrumbs.tsx | 12 +++++------- .../actions/app-slides-aside/app-slides-aside.tsx | 15 +++++++++++++-- .../deck/app-actions-deck/app-actions-deck.tsx | 13 +++++++++++++ .../app-actions-editor/app-actions-editor.tsx | 3 ++- .../app/pages/editor/app-editor/app-editor.tsx | 7 ++++++- .../app-slide-navigate/app-slide-navigate.tsx | 4 ++-- studio/src/app/utils/editor/deck.utils.ts | 10 +++++++++- studio/src/components.d.ts | 2 ++ 8 files changed, 52 insertions(+), 14 deletions(-) diff --git a/studio/src/app/components/editor/actions/app-breadcrumbs/app-breadcrumbs.tsx b/studio/src/app/components/editor/actions/app-breadcrumbs/app-breadcrumbs.tsx index af3b27a44..41f6af9fe 100644 --- a/studio/src/app/components/editor/actions/app-breadcrumbs/app-breadcrumbs.tsx +++ b/studio/src/app/components/editor/actions/app-breadcrumbs/app-breadcrumbs.tsx @@ -5,6 +5,8 @@ import editorStore from '../../../../stores/editor.store'; import {BreadcrumbsStep} from '../../../../types/editor/breadcrumbs-step'; +import {deckSelector, selectSlide} from '../../../../utils/editor/deck.utils'; + @Component({ tag: 'app-breadcrumbs', styleUrl: 'app-breadcrumbs.scss', @@ -25,15 +27,11 @@ export class AppBreadcrumbs { if (step === BreadcrumbsStep.DECK) { this.stepTo.emit(undefined); } else { - const deck = document.querySelector('main > deckgo-deck'); - - if (!deck) { - return; - } + const deck: HTMLDeckgoDeckElement = document.querySelector(deckSelector); - const index = await (deck as any).getActiveIndex(); + const index = await deck?.getActiveIndex(); - const slideElement: HTMLElement = deck.querySelector('.deckgo-slide-container:nth-child(' + (index + 1) + ')'); + const slideElement: HTMLElement | null = selectSlide({deck, index}); if (!slideElement) { return; diff --git a/studio/src/app/components/editor/actions/app-slides-aside/app-slides-aside.tsx b/studio/src/app/components/editor/actions/app-slides-aside/app-slides-aside.tsx index 685fabfe1..ddb20156e 100644 --- a/studio/src/app/components/editor/actions/app-slides-aside/app-slides-aside.tsx +++ b/studio/src/app/components/editor/actions/app-slides-aside/app-slides-aside.tsx @@ -5,7 +5,7 @@ import {ItemReorderEventDetail} from '@ionic/core'; import {debounce} from '@deckdeckgo/utils'; import {isSlide} from '../../../../../../../utils/deck/src'; -import {deckSelector, slideTo} from '../../../../utils/editor/deck.utils'; +import {deckSelector, slideTo, selectDeckSlide} from '../../../../utils/editor/deck.utils'; import {SlideUtils} from '../../../../utils/editor/slide.utils'; @Component({ @@ -30,6 +30,9 @@ export class AppSlidesAside { @Event() private reorder: EventEmitter; + @Event() + private stepTo: EventEmitter; + @State() private reorderDetail: ItemReorderEventDetail | undefined = undefined; @@ -187,6 +190,14 @@ export class AppSlidesAside { this.reorderDetail = undefined; } + private async slideTo(index: number) { + const slide: HTMLElement | null = selectDeckSlide(index); + + this.stepTo.emit(slide); + + await slideTo(index); + } + render() { return ( (this.hostRef = el as HTMLAppSlidesAsideElement)}> @@ -225,7 +236,7 @@ export class AppSlidesAside { return ( await slideTo(index)} + onClick={async () => await this.slideTo(index)} key={slide.getAttribute('slide_id')} slide={slide} deck={this.deckRef} diff --git a/studio/src/app/components/editor/actions/deck/app-actions-deck/app-actions-deck.tsx b/studio/src/app/components/editor/actions/deck/app-actions-deck/app-actions-deck.tsx index 8887e680a..825edd48a 100644 --- a/studio/src/app/components/editor/actions/deck/app-actions-deck/app-actions-deck.tsx +++ b/studio/src/app/components/editor/actions/deck/app-actions-deck/app-actions-deck.tsx @@ -14,6 +14,8 @@ import i18n from '../../../../../stores/i18n.store'; import {MoreAction} from '../../../../../types/editor/more-action'; +import {selectDeckSlide} from '../../../../../utils/editor/deck.utils'; + import {BackupOfflineService} from '../../../../../services/editor/backup/backup.offline.service'; import {AppIcon} from '../../../../core/app-icon/app-icon'; @@ -46,6 +48,9 @@ export class AppActionsDeck { @Event() private selectDeck: EventEmitter; + @Event() + private stepTo: EventEmitter; + private destroyListener; // Drag and drop is not supported on iOS and Firefox on Android @@ -75,6 +80,14 @@ export class AppActionsDeck { cssClass: 'popover-menu popover-menu-wide' }); + popover.onDidDismiss().then(async ({data}: OverlayEventDetail) => { + if (data !== undefined) { + const slide: HTMLElement | null = selectDeckSlide(data); + + this.stepTo.emit(slide); + } + }); + await popover.present(); } diff --git a/studio/src/app/components/editor/actions/footer/app-actions-editor/app-actions-editor.tsx b/studio/src/app/components/editor/actions/footer/app-actions-editor/app-actions-editor.tsx index 8c0f4b218..c5b9dede1 100644 --- a/studio/src/app/components/editor/actions/footer/app-actions-editor/app-actions-editor.tsx +++ b/studio/src/app/components/editor/actions/footer/app-actions-editor/app-actions-editor.tsx @@ -209,7 +209,8 @@ export class AppActionsEditor { toggleFullScreen={this.toggleFullScreen} actionPublish={this.actionPublish} deckDidChange={this.deckDidChange} - onSelectDeck={() => this.selectDeck()}> + onSelectDeck={() => this.selectDeck()} + onStepTo={($event: CustomEvent) => this.selectStep($event?.detail)}> ); } diff --git a/studio/src/app/pages/editor/app-editor/app-editor.tsx b/studio/src/app/pages/editor/app-editor/app-editor.tsx index b053e593d..c8afa65d8 100644 --- a/studio/src/app/pages/editor/app-editor/app-editor.tsx +++ b/studio/src/app/pages/editor/app-editor/app-editor.tsx @@ -852,7 +852,12 @@ export class AppEditor { return undefined; } - return ; + return ( + ) => this.selectStep($event)}> + ); } private renderSlidePreview() { diff --git a/studio/src/app/popovers/editor/app-slide-navigate/app-slide-navigate.tsx b/studio/src/app/popovers/editor/app-slide-navigate/app-slide-navigate.tsx index 164a90af2..406ab8083 100644 --- a/studio/src/app/popovers/editor/app-slide-navigate/app-slide-navigate.tsx +++ b/studio/src/app/popovers/editor/app-slide-navigate/app-slide-navigate.tsx @@ -28,9 +28,9 @@ export class AppSlideNavigate { } async jumpToSlide(index: number) { - await slideTo(index); + await (this.el.closest('ion-popover') as HTMLIonPopoverElement).dismiss(index); - await (this.el.closest('ion-popover') as HTMLIonPopoverElement).dismiss(); + await slideTo(index); } private onReorder($event: CustomEvent) { diff --git a/studio/src/app/utils/editor/deck.utils.ts b/studio/src/app/utils/editor/deck.utils.ts index 648c9cd40..130550781 100644 --- a/studio/src/app/utils/editor/deck.utils.ts +++ b/studio/src/app/utils/editor/deck.utils.ts @@ -2,5 +2,13 @@ export const deckSelector: string = 'app-editor > ion-content div.deck > main > export const slideTo = async (index: number) => { const deck: HTMLDeckgoDeckElement | undefined = document.querySelector(deckSelector); - await deck.slideTo(index); + await deck?.slideTo(index); +}; + +export const selectSlide = ({deck, index}: {deck: HTMLDeckgoDeckElement | null; index: number}): HTMLElement | null => + deck?.querySelector(':scope > .deckgo-slide-container:nth-child(' + (index + 1) + ')'); + +export const selectDeckSlide = (index: number): HTMLElement | null => { + const deck: HTMLDeckgoDeckElement | null = document.querySelector(deckSelector); + return selectSlide({deck, index}); }; diff --git a/studio/src/components.d.ts b/studio/src/components.d.ts index 9b0ef3cca..ccd617009 100644 --- a/studio/src/components.d.ts +++ b/studio/src/components.d.ts @@ -1312,6 +1312,7 @@ declare namespace LocalJSX { "deckDidChange"?: EventEmitter; "fullscreen"?: boolean; "onSelectDeck"?: (event: CustomEvent) => void; + "onStepTo"?: (event: CustomEvent) => void; "slides"?: JSX.IntrinsicElements[]; "toggleFullScreen"?: EventEmitter; } @@ -1683,6 +1684,7 @@ declare namespace LocalJSX { "activeIndex"?: number; "deckRef": HTMLDeckgoDeckElement; "onReorder"?: (event: CustomEvent) => void; + "onStepTo"?: (event: CustomEvent) => void; } interface AppSlotType { "onSelectType"?: (event: CustomEvent) => void; From c307ebd116ed31013b5a7d2a5c78b97ac4262029 Mon Sep 17 00:00:00 2001 From: peterpeterparker Date: Sat, 4 Sep 2021 09:25:08 +0200 Subject: [PATCH 2/2] refactor: use utils selector --- .../editor/slide/app-slide-preview/app-slide-preview.tsx | 3 ++- .../editor/slide/app-slide-warning/app-slide-warning.tsx | 9 +++++---- .../handlers/editor/events/deck/deck-events.handler.ts | 7 ++++--- .../editor/events/remote/remote-events.handler.ts | 4 ++-- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/studio/src/app/components/editor/slide/app-slide-preview/app-slide-preview.tsx b/studio/src/app/components/editor/slide/app-slide-preview/app-slide-preview.tsx index 246894bbc..a8f9f87a9 100644 --- a/studio/src/app/components/editor/slide/app-slide-preview/app-slide-preview.tsx +++ b/studio/src/app/components/editor/slide/app-slide-preview/app-slide-preview.tsx @@ -4,6 +4,7 @@ import {isSlide} from '@deckdeckgo/deck-utils'; import {debounce, isIOS, isLandscape} from '@deckdeckgo/utils'; import {SlotUtils} from '../../../../utils/editor/slot.utils'; +import {selectSlide} from '../../../../utils/editor/deck.utils'; @Component({ tag: 'app-slide-preview', @@ -95,7 +96,7 @@ export class AppSlidePreview { return; } - const slideElement: HTMLElement | undefined = this.deckRef?.querySelector('.deckgo-slide-container:nth-child(' + (index + 1) + ')'); + const slideElement: HTMLElement | undefined = selectSlide({deck: this.deckRef, index}); await this.updateSlide(slideElement); } diff --git a/studio/src/app/components/editor/slide/app-slide-warning/app-slide-warning.tsx b/studio/src/app/components/editor/slide/app-slide-warning/app-slide-warning.tsx index e9fc3836d..5fc20116d 100644 --- a/studio/src/app/components/editor/slide/app-slide-warning/app-slide-warning.tsx +++ b/studio/src/app/components/editor/slide/app-slide-warning/app-slide-warning.tsx @@ -11,8 +11,9 @@ import settingsStore from '../../../../stores/settings.store'; import {ContrastUtils} from '../../../../utils/editor/contrast.utils'; import {NodeUtils} from '../../../../utils/editor/node.utils'; import {SlotUtils} from '../../../../utils/editor/slot.utils'; +import {selectSlide} from '../../../../utils/editor/deck.utils'; -import { AppIcon } from '../../../core/app-icon/app-icon'; +import {AppIcon} from '../../../core/app-icon/app-icon'; @Component({ tag: 'app-slide-warning', @@ -186,7 +187,7 @@ export class AppSlideWarning { } private async getCurrentSlide(): Promise<{deck: HTMLElement | null; slide: HTMLElement | null}> { - const deck: HTMLElement = document.querySelector('main > deckgo-deck'); + const deck: HTMLDeckgoDeckElement = document.querySelector('main > deckgo-deck'); if (!deck) { return { @@ -195,11 +196,11 @@ export class AppSlideWarning { }; } - const index = await (deck as any).getActiveIndex(); + const index: number = await deck.getActiveIndex(); return { deck, - slide: deck.querySelector('.deckgo-slide-container:nth-child(' + (index + 1) + ')') as HTMLElement | null + slide: selectSlide({deck, index}) }; } diff --git a/studio/src/app/handlers/editor/events/deck/deck-events.handler.ts b/studio/src/app/handlers/editor/events/deck/deck-events.handler.ts index 72f8785c6..59f66f1bd 100644 --- a/studio/src/app/handlers/editor/events/deck/deck-events.handler.ts +++ b/studio/src/app/handlers/editor/events/deck/deck-events.handler.ts @@ -30,6 +30,7 @@ import {Utils} from '../../../../utils/core/utils'; import {SlotUtils} from '../../../../utils/editor/slot.utils'; import {ParseElementsUtils} from '../../../../utils/editor/parse-elements.utils'; import {SlideUtils} from '../../../../utils/editor/slide.utils'; +import {selectSlide} from '../../../../utils/editor/deck.utils'; import {DeckService} from '../../../../services/data/deck/deck.service'; import {SlideService} from '../../../../services/data/slide/slide.service'; @@ -926,15 +927,15 @@ export class DeckEventsHandler { } async toggleSlideEditable(editable: boolean) { - const deck: HTMLElement = this.mainRef.querySelector('deckgo-deck'); + const deck: HTMLDeckgoDeckElement = this.mainRef.querySelector('deckgo-deck'); if (!deck) { return; } - const index: number = await (deck as HTMLDeckgoDeckElement).getActiveIndex(); + const index: number = await deck.getActiveIndex(); - const slideElement: HTMLElement = deck.querySelector('.deckgo-slide-container:nth-child(' + (index + 1) + ')'); + const slideElement: HTMLElement = selectSlide({deck, index}); if (!slideElement) { return; diff --git a/studio/src/app/handlers/editor/events/remote/remote-events.handler.ts b/studio/src/app/handlers/editor/events/remote/remote-events.handler.ts index b8491f0a8..0de7eacda 100644 --- a/studio/src/app/handlers/editor/events/remote/remote-events.handler.ts +++ b/studio/src/app/handlers/editor/events/remote/remote-events.handler.ts @@ -9,7 +9,7 @@ import {ConnectionState, DeckdeckgoDeckDefinition, DeckdeckgoEventDeckRequest, D import {EnvironmentDeckDeckGoConfig} from '../../../../types/core/environment-config'; import {EnvironmentConfigService} from '../../../../services/environment/environment-config.service'; -import {deckSelector} from '../../../../utils/editor/deck.utils'; +import {deckSelector, selectSlide} from '../../../../utils/editor/deck.utils'; import {RemoteService} from '../../../../services/editor/remote/remote.service'; @@ -244,7 +244,7 @@ export class RemoteEventsHandler { const index = await deck.getActiveIndex(); - const youtubeSlideElement: any = this.el.querySelector('.deckgo-slide-container:nth-child(' + (index + 1) + ')'); + const youtubeSlideElement: HTMLDeckgoSlideYoutubeElement | null = selectSlide({deck, index}) as HTMLDeckgoSlideYoutubeElement | null; if (!youtubeSlideElement || youtubeSlideElement.tagName !== 'deckgo-slide-youtube'.toUpperCase()) { resolve();