From e1039aa2260a0e9d8ccca5a18ded480bf2f12530 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jovan=20Kruni=C4=87?= Date: Wed, 24 Apr 2019 09:11:24 +0200 Subject: [PATCH] feat(data): show skeleton screens before data is loaded Closes #4 --- src/app/_helpers/fake-backend.interceptor.ts | 6 ++--- src/app/modules/data/data.module.ts | 4 +++ .../data/detail/data-detail.component.ts | 19 +++++++------- src/app/modules/data/detail/data-detail.html | 12 ++++++--- .../elements/skeleton-list-item.component.ts | 22 ++++++++++++++++ .../data/elements/skeleton-list-item.html | 14 ++++++++++ .../skeleton-simple-card.component.ts | 22 ++++++++++++++++ .../data/elements/skeleton-simple-card.html | 8 ++++++ .../modules/data/list/data-list.component.ts | 26 ++++--------------- src/app/modules/data/list/data-list.html | 8 +++--- 10 files changed, 102 insertions(+), 39 deletions(-) create mode 100644 src/app/modules/data/elements/skeleton-list-item.component.ts create mode 100644 src/app/modules/data/elements/skeleton-list-item.html create mode 100644 src/app/modules/data/elements/skeleton-simple-card.component.ts create mode 100644 src/app/modules/data/elements/skeleton-simple-card.html diff --git a/src/app/_helpers/fake-backend.interceptor.ts b/src/app/_helpers/fake-backend.interceptor.ts index 9293dea8..f1442a03 100644 --- a/src/app/_helpers/fake-backend.interceptor.ts +++ b/src/app/_helpers/fake-backend.interceptor.ts @@ -17,7 +17,7 @@ import {HTTP_INTERCEPTORS, HttpClient, import {Injectable} from '@angular/core'; import {SCIndexResponse, SCThingType} from '@openstapps/core'; import {Observable, of} from 'rxjs'; -import {map} from 'rxjs/operators'; +import {map, delay} from 'rxjs/operators'; import {SampleThings} from './data/sample-things'; const sampleIndexResponse: SCIndexResponse = { @@ -150,12 +150,12 @@ export class FakeBackendInterceptor implements HttpInterceptor { return this.sampleFetcher.getSampleThing(request.body.filter.arguments.value) .pipe(map((sampleData: any) => { return new HttpResponse({status: 200, body: {data: sampleData}}); - })); + }), delay(1000)); // add delay for skeleton screens to be seen (see !16) } } return this.sampleFetcher.getSampleThings().pipe(map((sampleData: any) => { return new HttpResponse({status: 200, body: {data: sampleData}}); - })); + }), delay(1000)); // add delay for skeleton screens to be seen (see !16) } } return next.handle(request); diff --git a/src/app/modules/data/data.module.ts b/src/app/modules/data/data.module.ts index 824fee83..1a5cf6f3 100644 --- a/src/app/modules/data/data.module.ts +++ b/src/app/modules/data/data.module.ts @@ -60,6 +60,8 @@ import {SemesterDetailContentComponent} from './types/semester/semester-detail-c import {SemesterListItem} from './types/semester/semester-list-item.component'; import {VideoDetailContentComponent} from './types/video/video-detail-content.component'; import {VideoListItem} from './types/video/video-list-item.component'; +import {SkeletonListItem} from './elements/skeleton-list-item.component'; +import {SkeletonSimpleCard} from './elements/skeleton-simple-card.component'; @NgModule({ declarations: [ @@ -69,6 +71,7 @@ import {VideoListItem} from './types/video/video-list-item.component'; ArticleDetailContentComponent, ArticleListItem, SimpleCardComponent, + SkeletonSimpleCard, CatalogDetailContentComponent, CatalogListItem, DataDetailComponent, @@ -96,6 +99,7 @@ import {VideoListItem} from './types/video/video-list-item.component'; PlaceListItem, SemesterDetailContentComponent, SemesterListItem, + SkeletonListItem, VideoDetailContentComponent, VideoListItem, ], diff --git a/src/app/modules/data/detail/data-detail.component.ts b/src/app/modules/data/detail/data-detail.component.ts index 82bdf5f8..78546930 100644 --- a/src/app/modules/data/detail/data-detail.component.ts +++ b/src/app/modules/data/detail/data-detail.component.ts @@ -28,36 +28,37 @@ export class DataDetailComponent { dataProvider: DataProvider; item: SCThing; language: SCLanguageCode; + constructor(private route: ActivatedRoute, dataProvider: DataProvider, translateService: TranslateService) { this.dataProvider = dataProvider; this.language = translateService.currentLang as SCLanguageCode; - - // alert(translateService.currentLang); - translateService.onLangChange.subscribe((event: LangChangeEvent) => { this.language = event.lang as SCLanguageCode; }); } + /** * Provides data item with given UID * * @param uid Unique identifier of a thing */ - async getItem(uid: SCUuid): Promise { - return (await this.dataProvider.get(uid, DataScope.Remote)); + async getItem(uid: SCUuid): Promise { + this.dataProvider.get(uid, DataScope.Remote).then((data) => { + this.item = data; + }); } - async ngOnInit() { - this.item = await this.getItem(this.route.snapshot.paramMap.get('uid') || ''); + ngOnInit() { + this.getItem(this.route.snapshot.paramMap.get('uid') || ''); } /** * Updates the shown thing * - * @param refresher Refresher component the triggers the update + * @param refresher Refresher component that triggers the update */ async refresh(refresher: IonRefresher) { - this.item = await this.getItem(this.item.uid); + await this.getItem(this.item.uid); refresher.complete(); } } diff --git a/src/app/modules/data/detail/data-detail.html b/src/app/modules/data/detail/data-detail.html index a2b9e18c..8f4c0af8 100644 --- a/src/app/modules/data/detail/data-detail.html +++ b/src/app/modules/data/detail/data-detail.html @@ -7,12 +7,18 @@ {{'data.detail.TITLE' | translate}} - + - - + + + + + + + + diff --git a/src/app/modules/data/elements/skeleton-list-item.component.ts b/src/app/modules/data/elements/skeleton-list-item.component.ts new file mode 100644 index 00000000..72caf897 --- /dev/null +++ b/src/app/modules/data/elements/skeleton-list-item.component.ts @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2019 StApps + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ +import {Component} from '@angular/core'; + +@Component({ + selector: 'stapps-skeleton-list-item', + templateUrl: 'skeleton-list-item.html', +}) +export class SkeletonListItem { +} diff --git a/src/app/modules/data/elements/skeleton-list-item.html b/src/app/modules/data/elements/skeleton-list-item.html new file mode 100644 index 00000000..e9ac13b2 --- /dev/null +++ b/src/app/modules/data/elements/skeleton-list-item.html @@ -0,0 +1,14 @@ + + + + + + + +

+

+ +
+
+
+
diff --git a/src/app/modules/data/elements/skeleton-simple-card.component.ts b/src/app/modules/data/elements/skeleton-simple-card.component.ts new file mode 100644 index 00000000..a73f1920 --- /dev/null +++ b/src/app/modules/data/elements/skeleton-simple-card.component.ts @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2019 StApps + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ +import {Component} from '@angular/core'; + +@Component({ + selector: 'stapps-skeleton-simple-card', + templateUrl: 'skeleton-simple-card.html', +}) +export class SkeletonSimpleCard { +} diff --git a/src/app/modules/data/elements/skeleton-simple-card.html b/src/app/modules/data/elements/skeleton-simple-card.html new file mode 100644 index 00000000..a8f317c1 --- /dev/null +++ b/src/app/modules/data/elements/skeleton-simple-card.html @@ -0,0 +1,8 @@ + + + + + +

+
+
diff --git a/src/app/modules/data/list/data-list.component.ts b/src/app/modules/data/list/data-list.component.ts index 6da72370..f750f837 100644 --- a/src/app/modules/data/list/data-list.component.ts +++ b/src/app/modules/data/list/data-list.component.ts @@ -13,7 +13,7 @@ * this program. If not, see . */ import {Component} from '@angular/core'; -import {AlertController, LoadingController} from '@ionic/angular'; +import {AlertController} from '@ionic/angular'; import {SCThing} from '@openstapps/core'; import {Subject} from 'rxjs'; import {debounceTime, distinctUntilChanged} from 'rxjs/operators'; @@ -25,8 +25,9 @@ import {DataProvider} from '../data.provider'; }) export class DataListComponent { dataProvider: DataProvider; - items: SCThing[] = []; + items: SCThing[]; selectedItem: any; + loaded: boolean = false; size: number = 30; from: number = 0; @@ -34,10 +35,7 @@ export class DataListComponent { query: string; queryChanged: Subject = new Subject(); - loading: HTMLIonLoadingElement; - constructor( - private loadingController: LoadingController, private alertController: AlertController, dataProvider: DataProvider, ) { @@ -49,31 +47,19 @@ export class DataListComponent { .subscribe((model) => { this.from = 0; this.query = model; - this.items = []; this.fetchItems(); }); - this.fetchItems(); } private async fetchItems(): Promise { - if (this.from === 0) { - this.loading = await this.loadingController.create(); - await this.loading.present(); - } - return this.dataProvider.search({ from: this.from, query: this.query, size: this.size, } as any).then((result) => { - result.data.forEach((item) => { - this.items.push(item); - }); - - if (this.from === 0) { - this.loading.dismiss(); - } + this.items = result.data; + this.loaded = true; }, async (err) => { const alert: HTMLIonAlertElement = await this.alertController.create({ buttons: ['Dismiss'], @@ -82,8 +68,6 @@ export class DataListComponent { }); await alert.present(); - - await this.loading.dismiss(); }); } diff --git a/src/app/modules/data/list/data-list.html b/src/app/modules/data/list/data-list.html index beb9dcee..909e92e1 100644 --- a/src/app/modules/data/list/data-list.html +++ b/src/app/modules/data/list/data-list.html @@ -12,10 +12,12 @@ - - + + + + + -