Skip to content
This repository was archived by the owner on Feb 6, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {loadingController, popoverController} from '@ionic/core';

import {Deck} from '@deckdeckgo/editor';

import store from '../../../stores/error.store';
import errorStore from '../../../stores/error.store';
import i18n from '../../../stores/i18n.store';

import {clone} from '../../../utils/core/dashboard.utils';
Expand All @@ -19,7 +19,11 @@ import {AppIcon} from '../../core/app-icon/app-icon';
styleUrl: 'app-dashboard-deck-actions.scss'
})
export class AppDashboardDeckActions {
@Prop() deck: Deck;
@Prop()
deck: Deck;

@Prop()
disableDelete: boolean;

@Event() deckDeleted: EventEmitter<string>;
@Event() deckCloned: EventEmitter<void>;
Expand Down Expand Up @@ -71,7 +75,7 @@ export class AppDashboardDeckActions {

this.deckDeleted.emit(this.deck.id);
} catch (err) {
store.state.error = err;
errorStore.state.error = err;
}

await loading.dismiss();
Expand Down Expand Up @@ -100,7 +104,7 @@ export class AppDashboardDeckActions {

this.deckCloned.emit();
} catch (err) {
store.state.error = err;
errorStore.state.error = err;
}

await loading.dismiss();
Expand All @@ -111,19 +115,14 @@ export class AppDashboardDeckActions {
render() {
return (
<Host>
<button
onClick={($event: UIEvent) => this.cloneDeck($event)}
title={i18n.state.dashboard.copy}
disabled={this.actionInProgress}
class={this.actionInProgress ? 'disabled' : undefined}>
<button onClick={($event: UIEvent) => this.cloneDeck($event)} title={i18n.state.dashboard.copy} disabled={this.actionInProgress}>
<AppIcon name="copy" ariaLabel="" ariaHidden={true}></AppIcon>
</button>

<button
onClick={($event: UIEvent) => this.presentConfirmDelete($event)}
title={i18n.state.dashboard.delete}
disabled={this.actionInProgress}
class={this.actionInProgress ? 'disabled' : undefined}>
disabled={this.actionInProgress || this.disableDelete}>
<AppIcon name="trash" ariaLabel="" ariaHidden={true}></AppIcon>
</button>
</Host>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,13 +140,18 @@ export class AppNavigationActions {

return (
<Fragment>
<button class="ion-activatable" onClick={() => this.newDeck()} disabled={disabled} aria-label={i18n.state.tools.new_presentation}>
<button
key="new-deck-action"
class="ion-activatable"
onClick={() => this.newDeck()}
disabled={disabled}
aria-label={i18n.state.tools.new_presentation}>
<ion-ripple-effect></ion-ripple-effect>
<AppIcon name="document" ariaHidden={true} ariaLabel=""></AppIcon>
<ion-label>{i18n.state.tools.new}</ion-label>
</button>

<button class="ion-activatable" onClick={() => this.openFilePicker()} disabled={disabled}>
<button key="open-file-action" class="ion-activatable" onClick={() => this.openFilePicker()} disabled={disabled}>
<ion-ripple-effect></ion-ripple-effect>
<AppIcon name="folder-open" ariaHidden={true} ariaLabel=""></AppIcon>
<ion-label>{i18n.state.tools.open}</ion-label>
Expand All @@ -160,7 +165,7 @@ export class AppNavigationActions {
tabindex="-1"
/>

<button class="ion-activatable" onClick={() => this.exportData()}>
<button key="export-action" class="ion-activatable" onClick={() => this.exportData()}>
<ion-ripple-effect></ion-ripple-effect>
<AppIcon name="download" ariaHidden={true} ariaLabel=""></AppIcon>
<ion-label>{i18n.state.editor.export}</ion-label>
Expand All @@ -175,7 +180,7 @@ export class AppNavigationActions {
}

return (
<button class="ion-activatable" onClick={() => signIn()}>
<button key="sign-in-action" class="ion-activatable" onClick={() => signIn()}>
<ion-ripple-effect></ion-ripple-effect>
<AppIcon name="log-in" ariaHidden={true} ariaLabel=""></AppIcon>
<ion-label>{i18n.state.nav.sign_in}</ion-label>
Expand All @@ -189,7 +194,11 @@ export class AppNavigationActions {
<Fragment>
{this.renderCloudStatus()}

<button class="ion-activatable" onClick={(e: UIEvent) => this.openMenu(e)} aria-label={i18n.state.nav.menu}>
<button
key="user-menu-action"
class="ion-activatable"
onClick={(e: UIEvent) => this.openMenu(e)}
aria-label={i18n.state.nav.menu}>
<ion-ripple-effect></ion-ripple-effect>
<app-avatar src={userStore.state.photoUrl}></app-avatar>
<ion-label>{userStore.state.name ?? i18n.state.tools.user}</ion-label>
Expand All @@ -215,15 +224,21 @@ export class AppNavigationActions {
? i18n.state.sync.cloud_pending
: i18n.state.sync.cloud_idle;

const iconName: string =
syncStore.state.sync === 'error'
? 'cloud-offline'
: ['in_progress', 'pending'].includes(syncStore.state.sync)
? 'sync'
: 'cloud-done';

return (
<button class={`cloud ${syncStore.state.sync}`} aria-label={label} onClick={($event: UIEvent) => this.openSyncInfo($event)}>
{syncStore.state.sync === 'error' ? (
<AppIcon name="cloud-offline" ariaHidden={true} ariaLabel=""></AppIcon>
) : ['in_progress', 'pending'].includes(syncStore.state.sync) ? (
<AppIcon name="sync" ariaHidden={true} ariaLabel=""></AppIcon>
) : (
<AppIcon name="cloud-done" ariaHidden={true} ariaLabel=""></AppIcon>
)}
<button
key="cloud-status-action"
class={`cloud ion-activatable ${syncStore.state.sync}`}
aria-label={label}
onClick={($event: UIEvent) => this.openSyncInfo($event)}>
<ion-ripple-effect></ion-ripple-effect>
<AppIcon name={iconName} ariaHidden={true} ariaLabel=""></AppIcon>
<ion-label>{i18n.state.sync.cloud}</ion-label>
</button>
);
Expand Down
4 changes: 4 additions & 0 deletions studio/src/app/components/core/app-signin/app-signin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {EnvironmentCloud, EnvironmentDeckDeckGoConfig} from '../../../types/core

import {renderI18n} from '../../../utils/core/i18n.utils';
import {firebase, cloud} from '../../../utils/core/environment.utils';
import {removeSyncBeforeUnload} from '../../../utils/core/sync.window.utils';

@Component({
tag: 'app-signin',
Expand All @@ -34,6 +35,9 @@ export class AppSignIn {
await this.loadSignIn();

await this.initSignIn();

// We do not want to present a warning when user sign in
removeSyncBeforeUnload();
}

private onSignInSuccess = (credentials: {uid: string | undefined; githubAccessToken: string | undefined} | undefined) => {
Expand Down
2 changes: 0 additions & 2 deletions studio/src/app/pages/core/app-decks/app-decks.scss
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@ app-decks {
}

article {
cursor: pointer;

visibility: visible;
opacity: 1;

Expand Down
17 changes: 15 additions & 2 deletions studio/src/app/pages/core/app-decks/app-decks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import {ParseDeckSlotsUtils} from '../../../utils/editor/parse-deck-slots.utils'
import {ParseSlidesUtils} from '../../../utils/editor/parse-slides.utils';
import {TemplateUtils} from '../../../utils/editor/template.utils';
import {loadAndImport} from '../../../utils/core/dashboard.utils';
import {getEdit} from '../../../utils/editor/editor.utils';
import {removeSyncBeforeUnload} from '../../../utils/core/sync.window.utils';

import {decks} from '../../../providers/data/deck/deck.provider';
import {getSlide} from '../../../providers/data/slide/slide.provider';
Expand Down Expand Up @@ -50,6 +52,9 @@ export class AppDecks implements ComponentInterface {
@State()
private decksLoading: boolean = true;

@State()
private currentDeckId: string | undefined;

private readonly debounceLoading: () => void;
private readonly debounceDecksLoading: () => void;

Expand Down Expand Up @@ -77,6 +82,8 @@ export class AppDecks implements ComponentInterface {
});

await this.initDashboard();

this.currentDeckId = await getEdit();
}

private async initDashboard() {
Expand Down Expand Up @@ -223,6 +230,9 @@ export class AppDecks implements ComponentInterface {
}

private navigateReloadEditor() {
// We are aware a sync is going to happen and we are navigating programmatically
removeSyncBeforeUnload();

navStore.state.nav = {
url: '/',
direction: NavDirection.RELOAD
Expand Down Expand Up @@ -367,8 +377,10 @@ export class AppDecks implements ComponentInterface {
}

return (
<article key={deck.deck.id} onClick={() => this.navigateDeck(deck)}>
<ion-card class="item ion-no-margin">{this.renderDeck(deck)}</ion-card>
<article key={deck.deck.id}>
<ion-card custom-tappable class="item ion-no-margin" onClick={() => this.navigateDeck(deck)}>
{this.renderDeck(deck)}
</ion-card>

{this.renderAside(deck)}
</article>
Expand All @@ -384,6 +396,7 @@ export class AppDecks implements ComponentInterface {

<app-dashboard-deck-actions
deck={deck.deck}
disableDelete={deck.deck.id === this.currentDeckId}
onDeckDeleted={($event: CustomEvent) => this.removeDeletedDeck($event)}
onDeckCloned={() => this.navigateReloadEditor()}></app-dashboard-deck-actions>
</aside>
Expand Down
12 changes: 7 additions & 5 deletions studio/src/app/pages/editor/app-editor/app-editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ import {SlideTemplate, SyncEvent} from '@deckdeckgo/editor';

import {CreateSlidesUtils} from '../../../utils/editor/create-slides.utils';
import {ParseDeckSlotsUtils} from '../../../utils/editor/parse-deck-slots.utils';
import {getEdit} from '../../../utils/editor/editor.utils';
import {signIn as navigateSignIn} from '../../../utils/core/signin.utils';
import {SlideUtils} from '../../../utils/editor/slide.utils';

import {DeckEvents} from '../../../events/editor/deck/deck.events';
import {RemoteEvents} from '../../../events/editor/remote/remote.events';
Expand All @@ -32,13 +35,10 @@ import {SlideHelper} from '../../../helpers/editor/slide.helper';

import {SlotType} from '../../../types/editor/slot-type';

import {signIn as navigateSignIn} from '../../../utils/core/signin.utils';
import {SlideUtils} from '../../../utils/editor/slide.utils';

import {EnvironmentConfigService} from '../../../services/environment/environment-config.service';
import {FontsService} from '../../../services/editor/fonts/fonts.service';

import {sync} from '../../../providers/sync/sync.provider';
import {initSyncState, sync} from '../../../providers/sync/sync.provider';

import {EnvironmentGoogleConfig} from '../../../types/core/environment-config';

Expand Down Expand Up @@ -158,6 +158,8 @@ export class AppEditor {

await sync(data.data);
};

await initSyncState();
}

@Listen('reloadDeck', {target: 'document'})
Expand All @@ -175,7 +177,7 @@ export class AppEditor {
}

private async initOrFetch() {
const deckId: string | undefined = await get<string>('deckdeckgo_deck_id');
const deckId: string | undefined = await getEdit();

if (!deckId) {
await this.initSlide();
Expand Down
20 changes: 3 additions & 17 deletions studio/src/app/stores/sync.store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import {createStore} from '@stencil/store';

import {SyncState} from '@deckdeckgo/editor';

import {syncBeforeUnload} from '../utils/core/sync.window.utils';

interface SyncStore {
sync: SyncState;
}
Expand All @@ -10,22 +12,6 @@ const {state, onChange} = createStore<SyncStore>({
sync: 'idle'
});

const onBeforeUnload = ($event: BeforeUnloadEvent) => {
if (window.location.pathname === '/signin') {
// We do not want to present a warning when user sign in
return;
}

$event.preventDefault();
return ($event.returnValue = 'Are you sure you want to exit?');
};

onChange('sync', (sync: SyncState) => {
if (['pending', 'in_progress'].includes(sync)) {
window.addEventListener('beforeunload', onBeforeUnload, {capture: true});
} else {
window.removeEventListener('beforeunload', onBeforeUnload, {capture: true});
}
});
onChange('sync', (sync: SyncState) => syncBeforeUnload(sync));

export default {state, onChange};
22 changes: 22 additions & 0 deletions studio/src/app/utils/core/sync.window.utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import {SyncState} from '@deckdeckgo/editor';

const onBeforeUnload = ($event: BeforeUnloadEvent) => {
$event.preventDefault();
return ($event.returnValue = 'Are you sure you want to exit?');
};

const addSyncBeforeUnload = () => {
window.addEventListener('beforeunload', onBeforeUnload, {capture: true});
};

export const removeSyncBeforeUnload = () => {
window.removeEventListener('beforeunload', onBeforeUnload, {capture: true});
};

export const syncBeforeUnload = (sync: SyncState) => {
if (['pending', 'in_progress'].includes(sync)) {
addSyncBeforeUnload();
} else {
removeSyncBeforeUnload();
}
};
4 changes: 3 additions & 1 deletion studio/src/app/utils/editor/editor.utils.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import {del} from 'idb-keyval';
import {del, get} from 'idb-keyval';

import {clearSync} from '../../providers/sync/sync.provider';

import {ImageHistoryService} from '../../services/editor/image-history/image-history.service';

export const getEdit = (): Promise<string | undefined> => get('deckdeckgo_deck_id');

export const clearEdit = async (clearSyncData: boolean) => {
if (clearSyncData) {
await clearSync();
Expand Down
2 changes: 2 additions & 0 deletions studio/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ export namespace Components {
}
interface AppDashboardDeckActions {
"deck": Deck;
"disableDelete": boolean;
}
interface AppDeckFonts {
"deckElement": HTMLElement;
Expand Down Expand Up @@ -1409,6 +1410,7 @@ declare namespace LocalJSX {
}
interface AppDashboardDeckActions {
"deck"?: Deck;
"disableDelete"?: boolean;
"onDeckCloned"?: (event: CustomEvent<void>) => void;
"onDeckDeleted"?: (event: CustomEvent<string>) => void;
}
Expand Down
4 changes: 2 additions & 2 deletions studio/src/global/theme/mixins/_dashboard.scss
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@
color: var(--ion-color-dark);
}

&.disabled {
&[disabled] {
border: 1px solid var(--ion-color-light);

ion-icon {
color: var(--ion-color-light);
color: rgba(var(--ion-color-dark-rgb), 0.2);
}
}
}
Expand Down