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

Commit

Permalink
feat: storage / assets page (#1356)
Browse files Browse the repository at this point in the history
* feat: init storage page

* style: remove extra space around inline button

* feat: slower loading to avoid visual glitch

* feat: list images and data in storage page

* fix: cmp tag

* feat: rename storage text to assets

* feat: rename storage text to assets

* feat: rename storage to assets

* feat: rename storage to assets

* refactor: rename assets route is reserved keywords

* refactor: component for data

* style: display image title

* refactor: cmp photo to unsplash

* feat: unsplash use new assets layout

* fix: grid

* fix: searching

* feat: gif use new assets layout

* refactor: rename cmp image

* feat: extract and rebuild image history

* feat: remove unused component

* refactor: rename storage components

* feat: add waves to history

* fix: history waves push

* style: asset image columns

* style: spacing

* feat: gif and unsplash alt

* style: spacing

* feat: text about assets
  • Loading branch information
peterpeterparker authored Oct 17, 2021
1 parent 6cafeda commit ad34a3b
Show file tree
Hide file tree
Showing 56 changed files with 1,693 additions and 1,663 deletions.
1 change: 1 addition & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ Some bugs (sh\*t happens) might not yet been reported. Likewise, your awesome id
## Translations (i18n)

We would be grateful to get your help to translate our apps:

- Editor
- Site
- Remote
Expand Down
2 changes: 2 additions & 0 deletions studio/src/app/app-root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,8 @@ export class AppRoot {

<ion-route url="/decks" component="app-decks" />

<ion-route url="/storage" component="app-storage" />

<ion-route url="/signin" component="app-signin-page" />

<ion-route url="/poll" component="app-poll" />
Expand Down
20 changes: 18 additions & 2 deletions studio/src/app/components/core/app-menu/app-menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ export class AppMenu {
{this.renderUser()}

{this.renderEditor()}
{this.renderDashboard()}

{this.renderDecks()}
{this.renderStorage()}

{this.renderSettings()}

{this.renderInteract()}
Expand Down Expand Up @@ -52,7 +55,7 @@ export class AppMenu {
);
}

private renderDashboard() {
private renderDecks() {
if (!this.signIn) {
return undefined;
}
Expand All @@ -65,6 +68,19 @@ export class AppMenu {
);
}

private renderStorage() {
if (!this.signIn) {
return undefined;
}

return (
<ion-item button href="/storage" routerDirection="forward">
<AppIcon name="storage" path="icons" ariaLabel="" ariaHidden={true} lazy={true} slot="start"></AppIcon>
<ion-label>{i18n.state.menu.assets}</ion-label>
</ion-item>
);
}

private renderInteract() {
return (
<Fragment>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
@use "../../../../global/theme/mixins/assets";

app-storage-files {
@include assets.assets;
}
138 changes: 138 additions & 0 deletions studio/src/app/components/core/app-storage-files/app-storage-files.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
import {Component, ComponentInterface, EventEmitter, h, Host, State, Event, Prop, Watch} from '@stencil/core';

import {StorageFile, StorageFilesList} from '@deckdeckgo/editor';

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

import {Constants} from '../../../types/core/constants';

import {getFiles} from '../../../providers/storage/storage.provider';

@Component({
tag: 'app-storage-files',
styleUrl: 'app-storage-files.scss'
})
export class AppStorageFiles implements ComponentInterface {
private paginationNext: string | null;

@Prop()
folder!: 'data' | 'images';

@State()
private loading: boolean = true;

@State()
private disableInfiniteScroll = false;

@State()
private files: StorageFile[] = [];

@Event()
selectAsset: EventEmitter<StorageFile>;

componentWillLoad() {
this.search().then(() => {});
}

@Watch('folder')
async onFolderChange() {
this.disableInfiniteScroll = false;
this.files = [];
this.loading = true;

await this.search();
}

private async search() {
const {items, nextPageToken}: StorageFilesList = await this.loadFiles();

this.files = [...this.files, ...items];
this.paginationNext = nextPageToken;

this.disableInfiniteScroll = items.length < Constants.STORAGE.MAX_QUERY_RESULTS - 1 || !this.paginationNext;

this.loading = false;
}

private async loadFiles(): Promise<StorageFilesList> {
try {
const list: StorageFilesList = await getFiles({next: this.paginationNext, folder: this.folder});

if (!list || !list.items || list.items.length <= 0) {
return {
items: [],
nextPageToken: null
};
}

return list;
} catch (err) {
store.state.error = 'Storage files cannot be loaded.';

return {
items: [],
nextPageToken: null
};
}
}

private async searchNext($event: CustomEvent<void>) {
await this.search();

await ($event.target as HTMLIonInfiniteScrollElement).complete();
}

render() {
return (
<Host>
{this.renderContent()}

<ion-infinite-scroll
threshold="100px"
disabled={this.disableInfiniteScroll}
onIonInfinite={async ($event: CustomEvent<void>) => await this.searchNext($event)}>
<ion-infinite-scroll-content loadingText={i18n.state.core.loading}></ion-infinite-scroll-content>
</ion-infinite-scroll>
</Host>
);
}

private renderContent() {
if (!this.files || this.files.length <= 0) {
return this.renderPlaceHolder();
}

return this.renderFiles();
}

private renderPlaceHolder() {
if (this.loading) {
return undefined;
}

return <ion-label class="empty">{i18n.state.editor.your_collection_empty}</ion-label>;
}

private renderFiles() {
return this.files.map((storageFile: StorageFile, index: number) => {
return this.renderFile(storageFile, index);
});
}

private renderFile(storageFile: StorageFile, index: number) {
if (this.folder === 'images') {
return (
<article custom-tappable onClick={() => this.selectAsset.emit(storageFile)} key={`file-${index}`}>
<app-asset-image image={storageFile}></app-asset-image>
</article>
);
}

return (
<article custom-tappable onClick={() => this.selectAsset.emit(storageFile)} key={`file-${index}`}>
<app-asset-data data={storageFile}></app-asset-data>
</article>
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
app-asset-data {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;

margin: 16px 0;

ion-icon {
font-size: 3rem;
}

ion-label {
max-width: calc(100% - 32px);
text-align: center;
padding-top: 4px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
font-size: var(--font-size-very-small);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import {Component, ComponentInterface, h, Host, Prop} from '@stencil/core';
import {AppIcon} from '../../app-icon/app-icon';
import {StorageFile} from '@deckdeckgo/editor';

@Component({
tag: 'app-asset-data',
styleUrl: 'app-asset-data.scss'
})
export class AppAssetData implements ComponentInterface {
@Prop()
data!: StorageFile;

render() {
return (
<Host>
<AppIcon name="document" ariaHidden={true} ariaLabel=""></AppIcon>
<ion-label>{this.data.name}</ion-label>
</Host>
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
app-asset-image {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 100%;

div.image-container {
border-radius: 4px;
overflow: hidden;
position: relative;

display: block;

&.waves {
display: flex;
flex-direction: column;
height: 56px;
justify-content: flex-start;

svg[wave="upward"] {
margin-top: auto;
}
}
}

&.imgLoaded {
div.image-container {
box-shadow: 1px 2px 8px 2px rgba(var(--ion-color-dark-rgb), 0.2);
}
}

deckgo-lazy-img {
--deckgo-lazy-img-width: 100%;
--deckgo-lazy-img-height: auto;
--deckgo-lazy-img-min-height: var(--deckgo-images-min-height);
--deckgo-lazy-img-vertical-align: top;
}

ion-label {
max-width: calc(100% - 32px);
padding-top: 4px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
font-size: var(--font-size-very-small);
display: inline-block;
margin-top: 4px;
}

ion-label.photo-credits {
position: absolute;
bottom: 0;
right: 0;
background: rgba(0, 0, 0, 0.4);
padding: 4px 8px;
font-size: var(--deckgo-images-font-size, var(--font-size-very-small));
color: white;

a {
color: white;
text-decoration: inherit;

&:hover,
&:active {
color: white;
}
}
}
}
Loading

0 comments on commit ad34a3b

Please sign in to comment.