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

Commit e080749

Browse files
feat: reorder slides (gui)
1 parent 4f0bc3e commit e080749

File tree

3 files changed

+62
-7
lines changed

3 files changed

+62
-7
lines changed

studio/src/app/modals/editor/app-slide-navigate/app-slide-navigate.tsx

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import {Component, Listen, Element, State, h} from '@stencil/core';
1+
import {Component, Listen, Element, State, h, EventEmitter, Event} from '@stencil/core';
2+
import {ItemReorderEventDetail} from '@ionic/core';
23

34
@Component({
45
tag: 'app-slide-navigate',
@@ -11,6 +12,8 @@ export class AppSlideNavigate {
1112
@State()
1213
slides: string[];
1314

15+
@Event() private reorder: EventEmitter<ItemReorderEventDetail>;
16+
1417
async componentDidLoad() {
1518
history.pushState({modal: true}, null);
1619

@@ -26,7 +29,7 @@ export class AppSlideNavigate {
2629
await (this.el.closest('ion-modal') as HTMLIonModalElement).dismiss();
2730
}
2831

29-
private async jumpToSlide(index: number) {
32+
async jumpToSlide(index: number) {
3033
await (this.el.closest('ion-modal') as HTMLIonModalElement).dismiss(index);
3134
}
3235

@@ -71,6 +74,19 @@ export class AppSlideNavigate {
7174
});
7275
}
7376

77+
private onReorder($event: CustomEvent<ItemReorderEventDetail>): Promise<void> {
78+
return new Promise<void>((resolve) => {
79+
if (!$event) {
80+
resolve();
81+
return;
82+
}
83+
84+
this.reorder.emit($event.detail);
85+
86+
resolve();
87+
});
88+
}
89+
7490
render() {
7591
return [
7692
<ion-header>
@@ -84,9 +100,9 @@ export class AppSlideNavigate {
84100
</ion-toolbar>
85101
</ion-header>,
86102
<ion-content class="ion-padding">
87-
<ion-list>
103+
<ion-reorder-group onIonItemReorder={($event: CustomEvent<ItemReorderEventDetail>) => this.onReorder($event)} disabled={!this.slides || this.slides.length <= 1}>
88104
{this.renderSlides()}
89-
</ion-list>
105+
</ion-reorder-group>
90106
</ion-content>
91107
];
92108
}
@@ -100,6 +116,7 @@ export class AppSlideNavigate {
100116

101117
return <ion-item ion-item button onClick={() => this.jumpToSlide(i)}>
102118
<ion-label>{text}</ion-label>
119+
<ion-reorder slot="end"></ion-reorder>
103120
</ion-item>
104121
})
105122
);

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

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import {AnonymousService} from '../../../services/editor/anonymous/anonymous.ser
2525
import {NavDirection, NavService} from '../../../services/core/nav/nav.service';
2626
import {DeckEditorService} from '../../../services/editor/deck/deck-editor.service';
2727
import {BusyService} from '../../../services/editor/busy/busy.service';
28+
import {ItemReorderEventDetail} from '@ionic/core';
2829

2930
@Component({
3031
tag: 'app-editor',
@@ -87,7 +88,7 @@ export class AppEditor {
8788
this.busyService = BusyService.getInstance();
8889
}
8990

90-
@Listen('ionRouteDidChange', { target: 'window' })
91+
@Listen('ionRouteDidChange', {target: 'window'})
9192
async onRouteDidChange($event: CustomEvent) {
9293
if (!$event || !$event.detail) {
9394
return;
@@ -479,6 +480,37 @@ export class AppEditor {
479480
this.hideNavigation = $event ? DeckDeckGoUtils.isIOS() && $event.detail : false;
480481
}
481482

483+
@Listen('reorder', {target: 'document'})
484+
async onReorderSlides($event: CustomEvent<ItemReorderEventDetail>) {
485+
if (!$event || !$event.detail) {
486+
return;
487+
}
488+
489+
await this.reorderSlides($event.detail);
490+
}
491+
492+
private reorderSlides(detail: ItemReorderEventDetail): Promise<void> {
493+
return new Promise<void>((resolve) => {
494+
if (!detail) {
495+
resolve();
496+
return;
497+
}
498+
499+
if (detail.from < 0 || detail.to < 0 || !this.slides || detail.to >= this.slides.length || detail.from === detail.to) {
500+
resolve();
501+
return;
502+
}
503+
504+
this.slides.splice(detail.to, 0, ...this.slides.splice(detail.from, 1));
505+
this.slides = [...this.slides];
506+
507+
// Finish the reorder and position the item in the DOM based on where the gesture ended. This method can also be called directly by the reorder group
508+
detail.complete();
509+
510+
resolve();
511+
});
512+
}
513+
482514
render() {
483515
return [
484516
<app-navigation publish={true} class={this.hideNavigation ? 'hidden' : undefined}></app-navigation>,
@@ -502,7 +534,8 @@ export class AppEditor {
502534
<app-editor-toolbar></app-editor-toolbar>
503535
</ion-content>,
504536
<ion-footer class={this.presenting ? 'idle' : undefined}>
505-
<app-editor-actions hideFooterActions={this.hideFooterActions} fullscreen={this.fullscreen} slides={this.slides}
537+
<app-editor-actions hideFooterActions={this.hideFooterActions} fullscreen={this.fullscreen}
538+
slides={this.slides}
506539
onSignIn={() => this.signIn()}
507540
onAddSlide={($event: CustomEvent<any>) => this.addSlide($event)}
508541
onAnimatePrevNextSlide={($event: CustomEvent<boolean>) => this.animatePrevNextSlide($event)}

studio/src/components.d.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ import {
1515
import {
1616
MoreAction,
1717
} from './app/utils/editor/more-action';
18+
import {
19+
ItemReorderEventDetail,
20+
} from '@ionic/core';
1821

1922
export namespace Components {
2023
interface AppAbout {}
@@ -637,7 +640,9 @@ declare namespace LocalJSX {
637640
'redirect'?: string;
638641
'redirectId'?: string;
639642
}
640-
interface AppSlideNavigate extends JSXBase.HTMLAttributes<HTMLAppSlideNavigateElement> {}
643+
interface AppSlideNavigate extends JSXBase.HTMLAttributes<HTMLAppSlideNavigateElement> {
644+
'onReorder'?: (event: CustomEvent<ItemReorderEventDetail>) => void;
645+
}
641646
interface AppSlotType extends JSXBase.HTMLAttributes<HTMLAppSlotTypeElement> {
642647
'selectedElement'?: HTMLElement;
643648
}

0 commit comments

Comments
 (0)