forked from CIT/Vmeda.Online
		
	MOBILE-2554 core: Create infinite scroll component
This commit is contained in:
		
							parent
							
								
									2b3ebc5452
								
							
						
					
					
						commit
						bf2c75c148
					
				| @ -29,12 +29,7 @@ | ||||
|                 </a> | ||||
|             </ion-list> | ||||
| 
 | ||||
|             <div *ngIf="canLoadMore" padding> | ||||
|                 <button ion-button block (click)="fetchEvents()" color="light">{{'core.loadmore' | translate }}</button> | ||||
|                 <ion-infinite-scroll [enabled]="canLoadMore" (ionInfinite)="$event.waitFor(fetchEvents())"> | ||||
|                    <ion-infinite-scroll-content></ion-infinite-scroll-content> | ||||
|                 </ion-infinite-scroll> | ||||
|             </div> | ||||
|             <core-infinite-loading [enabled]="canLoadMore" (action)="loadMoreEvents($event)"></core-infinite-loading> | ||||
|         </core-loading> | ||||
|     </ion-content> | ||||
| </core-split-view> | ||||
| @ -179,6 +179,18 @@ export class AddonCalendarListPage implements OnDestroy { | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Function to load more events. | ||||
|      * | ||||
|      * @param {any} [infiniteComplete] Infinite scroll complete function. Only used from core-infinite-loading. | ||||
|      * @return {Promise<any>} Resolved when done. | ||||
|      */ | ||||
|     loadMoreEvents(infiniteComplete?: any): Promise<any> { | ||||
|         return this.fetchEvents().finally(() => { | ||||
|             infiniteComplete && infiniteComplete(); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Get filtered events. | ||||
|      * | ||||
|  | ||||
| @ -15,12 +15,7 @@ | ||||
| <ion-content class="has-footer"> | ||||
|     <core-loading [hideUntil]="loaded"> | ||||
|         <!-- Load previous messages. --> | ||||
|         <div *ngIf="canLoadMore" padding> | ||||
|             <ion-infinite-scroll [enabled]="canLoadMore" (ionInfinite)="loadPrevious($event)" position="top"> | ||||
|                <ion-infinite-scroll-content></ion-infinite-scroll-content> | ||||
|             </ion-infinite-scroll> | ||||
|             <button ion-button block (click)="loadPrevious()" color="light">{{'core.loadmore' | translate }}</button> | ||||
|         </div> | ||||
|         <core-infinite-loading [enabled]="canLoadMore" (action)="loadPrevious($event)" position="top"></core-infinite-loading> | ||||
|         <ion-list class="addon-messages-discussion-container" [attr.aria-live]="polite"> | ||||
|             <ng-container *ngFor="let message of messages; index as index; last as last"> | ||||
|                 <ion-chip *ngIf="showDate(message, messages[index - 1])" class="addon-messages-date" color="light"> | ||||
|  | ||||
| @ -543,10 +543,10 @@ export class AddonMessagesDiscussionPage implements OnDestroy { | ||||
|     /** | ||||
|      * Function to load previous messages. | ||||
|      * | ||||
|      * @param {any} [infiniteScroll] Infinite scroll object. | ||||
|      * @param {any} [infiniteComplete] Infinite scroll complete function. Only used from core-infinite-loading. | ||||
|      * @return {Promise<any>} Resolved when done. | ||||
|      */ | ||||
|     loadPrevious(infiniteScroll: any): Promise<any> { | ||||
|     loadPrevious(infiniteComplete?: any): Promise<any> { | ||||
|         // If there is an ongoing fetch, wait for it to finish.
 | ||||
|         return this.waitForFetch().finally(() => { | ||||
|             this.pagesLoaded++; | ||||
| @ -555,7 +555,7 @@ export class AddonMessagesDiscussionPage implements OnDestroy { | ||||
|                 this.pagesLoaded--; | ||||
|                 this.domUtils.showErrorModalDefault(error, 'addon.messages.errorwhileretrievingmessages', true); | ||||
|             }).finally(() => { | ||||
|                 infiniteScroll.complete(); | ||||
|                 infiniteComplete && infiniteComplete(); | ||||
|             }); | ||||
|         }); | ||||
|     } | ||||
|  | ||||
| @ -88,12 +88,7 @@ | ||||
|                 </div> | ||||
|             </core-empty-box> | ||||
| 
 | ||||
|             <div *ngIf="canLoadMore" padding> | ||||
|                 <button ion-button block (click)="fetchMoreDiscussions()" color="light">{{'core.loadmore' | translate }}</button> | ||||
|                 <ion-infinite-scroll [enabled]="canLoadMore" (ionInfinite)="$event.waitFor(fetchMoreDiscussions())"> | ||||
|                     <ion-infinite-scroll-content></ion-infinite-scroll-content> | ||||
|                 </ion-infinite-scroll> | ||||
|             </div> | ||||
|             <core-infinite-loading [enabled]="canLoadMore" (action)="fetchMoreDiscussions($event)"></core-infinite-loading> | ||||
|         </core-loading> | ||||
| 
 | ||||
|         <ion-fab bottom end *ngIf="forum && forum.cancreatediscussions"> | ||||
|  | ||||
| @ -305,13 +305,16 @@ export class AddonModForumIndexComponent extends CoreCourseModuleMainActivityCom | ||||
|     /** | ||||
|      * Convenience function to load more forum discussions. | ||||
|      * | ||||
|      * @param {any} [infiniteComplete] Infinite scroll complete function. Only used from core-infinite-loading. | ||||
|      * @return {Promise<any>} Promise resolved when done. | ||||
|      */ | ||||
|     protected fetchMoreDiscussions(): Promise<any> { | ||||
|     fetchMoreDiscussions(infiniteComplete?: any): Promise<any> { | ||||
|         return this.fetchDiscussions(false).catch((message) => { | ||||
|             this.domUtils.showErrorModalDefault(message, 'addon.mod_forum.errorgetforum', true); | ||||
| 
 | ||||
|             this.canLoadMore = false; // Set to false to prevent infinite calls with infinite-loading.
 | ||||
|         }).finally(() => { | ||||
|             infiniteComplete && infiniteComplete(); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -56,12 +56,7 @@ | ||||
| 
 | ||||
|             <core-empty-box *ngIf="!entries.length && !offlineEntries.length" icon="list" [message]="'addon.mod_glossary.noentriesfound' | translate"></core-empty-box> | ||||
| 
 | ||||
|             <div *ngIf="canLoadMore" padding> | ||||
|                 <button ion-button block (click)="loadMoreEntries()" color="light">{{'core.loadmore' | translate }}</button> | ||||
|                 <ion-infinite-scroll [enabled]="canLoadMore" (ionInfinite)="$event.waitFor(loadMoreEntries())"> | ||||
|                     <ion-infinite-scroll-content></ion-infinite-scroll-content> | ||||
|                 </ion-infinite-scroll> | ||||
|             </div> | ||||
|             <core-infinite-loading [enabled]="canLoadMore" (action)="loadMoreEntries($event)"></core-infinite-loading> | ||||
|         </core-loading> | ||||
| 
 | ||||
|         <ion-fab bottom end *ngIf="canAdd"> | ||||
|  | ||||
| @ -289,11 +289,14 @@ export class AddonModGlossaryIndexComponent extends CoreCourseModuleMainActivity | ||||
|     /** | ||||
|      * Convenience function to load more forum discussions. | ||||
|      * | ||||
|      * @param {any} [infiniteComplete] Infinite scroll complete function. Only used from core-infinite-loading. | ||||
|      * @return {Promise<any>} Promise resolved when done. | ||||
|      */ | ||||
|     loadMoreEntries(): Promise<any> { | ||||
|     loadMoreEntries(infiniteComplete?: any): Promise<any> { | ||||
|         return this.fetchEntries(true).catch((error) => { | ||||
|             this.domUtils.showErrorModalDefault(error, 'addon.mod_glossary.errorloadingentries', true); | ||||
|         }).finally(() => { | ||||
|             infiniteComplete && infiniteComplete(); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -32,11 +32,6 @@ | ||||
|             <addon-notifications-actions [contextUrl]="notification.contexturl" [courseId]="notification.courseid"></addon-notifications-actions> | ||||
|         </ion-card> | ||||
|         <core-empty-box *ngIf="!notifications || notifications.length <= 0" icon="notifications" [message]="'addon.notifications.therearentnotificationsyet' | translate"></core-empty-box> | ||||
|         <div *ngIf="canLoadMore" padding> | ||||
|             <button ion-button block (click)="loadMoreNotifications()" color="light">{{'core.loadmore' | translate }}</button> | ||||
|             <ion-infinite-scroll [enabled]="canLoadMore" (ionInfinite)="loadMoreNotifications($event)"> | ||||
|                 <ion-infinite-scroll-content></ion-infinite-scroll-content> | ||||
|             </ion-infinite-scroll> | ||||
|         </div> | ||||
|         <core-infinite-loading [enabled]="canLoadMore" (action)="loadMoreNotifications($event)"></core-infinite-loading> | ||||
|     </core-loading> | ||||
| </ion-content> | ||||
|  | ||||
| @ -204,11 +204,11 @@ export class AddonNotificationsListPage { | ||||
|     /** | ||||
|      * Load more results. | ||||
|      * | ||||
|      * @param {any} infiniteScroll The infinit scroll instance. | ||||
|      * @param {any} [infiniteComplete] Infinite scroll complete function. Only used from core-infinite-loading. | ||||
|      */ | ||||
|     loadMoreNotifications(infiniteScroll: any): void { | ||||
|     loadMoreNotifications(infiniteComplete?: any): void { | ||||
|         this.fetchNotifications().finally(() => { | ||||
|             infiniteScroll.complete(); | ||||
|             infiniteComplete && infiniteComplete(); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -49,6 +49,7 @@ import { CoreNavigationBarComponent } from './navigation-bar/navigation-bar'; | ||||
| import { CoreAttachmentsComponent } from './attachments/attachments'; | ||||
| import { CoreIonTabsComponent } from './ion-tabs/ion-tabs'; | ||||
| import { CoreIonTabComponent } from './ion-tabs/ion-tab'; | ||||
| import { CoreInfiniteLoadingComponent } from './infinite-loading/infinite-loading'; | ||||
| 
 | ||||
| @NgModule({ | ||||
|     declarations: [ | ||||
| @ -83,7 +84,8 @@ import { CoreIonTabComponent } from './ion-tabs/ion-tab'; | ||||
|         CoreNavigationBarComponent, | ||||
|         CoreAttachmentsComponent, | ||||
|         CoreIonTabsComponent, | ||||
|         CoreIonTabComponent | ||||
|         CoreIonTabComponent, | ||||
|         CoreInfiniteLoadingComponent | ||||
|     ], | ||||
|     entryComponents: [ | ||||
|         CoreContextMenuPopoverComponent, | ||||
| @ -125,7 +127,8 @@ import { CoreIonTabComponent } from './ion-tabs/ion-tab'; | ||||
|         CoreNavigationBarComponent, | ||||
|         CoreAttachmentsComponent, | ||||
|         CoreIonTabsComponent, | ||||
|         CoreIonTabComponent | ||||
|         CoreIonTabComponent, | ||||
|         CoreInfiniteLoadingComponent | ||||
|     ] | ||||
| }) | ||||
| export class CoreComponentsModule {} | ||||
|  | ||||
							
								
								
									
										19
									
								
								src/components/infinite-loading/core-infinite-loading.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								src/components/infinite-loading/core-infinite-loading.html
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,19 @@ | ||||
| <div *ngIf="enabled && !loadingMore && position != 'top'" padding-horizontal> | ||||
|     <button ion-button block (click)="loadMore()" color="light"> | ||||
|         {{'core.loadmore' | translate }} | ||||
|     </button> | ||||
| </div> | ||||
| 
 | ||||
| <ion-infinite-scroll [enabled]="enabled && !loadingMore" (ionInfinite)="loadMore($event)" [position]="position"> | ||||
|     <ion-infinite-scroll-content></ion-infinite-scroll-content> | ||||
| </ion-infinite-scroll> | ||||
| 
 | ||||
| <div *ngIf="enabled && !loadingMore && position == 'top'" padding-horizontal> | ||||
|     <button ion-button block (click)="loadMore()" color="light"> | ||||
|         {{'core.loadmore' | translate }} | ||||
|     </button> | ||||
| </div> | ||||
| 
 | ||||
| <div *ngIf="loadingMore" padding text-center> | ||||
|     <ion-spinner></ion-spinner> | ||||
| </div> | ||||
							
								
								
									
										68
									
								
								src/components/infinite-loading/infinite-loading.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								src/components/infinite-loading/infinite-loading.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,68 @@ | ||||
| // (C) Copyright 2015 Martin Dougiamas
 | ||||
| //
 | ||||
| // Licensed under the Apache License, Version 2.0 (the "License");
 | ||||
| // you may not use this file except in compliance with the License.
 | ||||
| // You may obtain a copy of the License at
 | ||||
| //
 | ||||
| //     http://www.apache.org/licenses/LICENSE-2.0
 | ||||
| //
 | ||||
| // Unless required by applicable law or agreed to in writing, software
 | ||||
| // distributed under the License is distributed on an "AS IS" BASIS,
 | ||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | ||||
| // See the License for the specific language governing permissions and
 | ||||
| // limitations under the License.
 | ||||
| 
 | ||||
| import { Component, Input, Output, EventEmitter } from '@angular/core'; | ||||
| import { InfiniteScroll } from 'ionic-angular'; | ||||
| 
 | ||||
| /** | ||||
|  * Component to show a infinite loading trigger and spinner while more data is being loaded. | ||||
|  * | ||||
|  * Usage: | ||||
|  * <core-infinite-loading [action]="loadingAction" [enabled]="dataLoaded"></core-inifinite-loading> | ||||
|  */ | ||||
| @Component({ | ||||
|     selector: 'core-infinite-loading', | ||||
|     templateUrl: 'core-infinite-loading.html', | ||||
| }) | ||||
| export class CoreInfiniteLoadingComponent { | ||||
|     @Input() enabled: boolean; | ||||
|     @Input() position = 'bottom'; | ||||
|     @Output() action: EventEmitter<() => void>; // Will emit an event when triggered.
 | ||||
| 
 | ||||
|     loadingMore = false;   // Hide button and avoid loading more.
 | ||||
| 
 | ||||
|     protected infiniteScroll: InfiniteScroll; | ||||
| 
 | ||||
|     constructor() { | ||||
|         this.action = new EventEmitter(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Load More items calling the action provided. | ||||
|      * | ||||
|      * @param {InfiniteScroll} [infiniteScroll] Infinite scroll object only if triggered from the scroll. | ||||
|      */ | ||||
|     loadMore(infiniteScroll?: InfiniteScroll): void { | ||||
|         if (this.loadingMore) { | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         if (infiniteScroll) { | ||||
|             this.infiniteScroll = infiniteScroll; | ||||
|         } | ||||
|         this.loadingMore = true; | ||||
| 
 | ||||
|         this.action.emit(this.complete.bind(this)); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Complete loading. | ||||
|      */ | ||||
|     complete(): void { | ||||
|         this.loadingMore = false; | ||||
|         this.infiniteScroll && this.infiniteScroll.complete(); | ||||
|         this.infiniteScroll = undefined; | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -51,12 +51,7 @@ | ||||
|                 </ng-container> | ||||
|             </core-dynamic-component> | ||||
| 
 | ||||
|             <div *ngIf="canLoadMore" padding> | ||||
|                 <button ion-button block (click)="showMoreActivities()" color="light">{{'core.loadmore' | translate }}</button> | ||||
|                 <ion-infinite-scroll [enabled]="canLoadMore" (ionInfinite)="$event.waitFor(showMoreActivities())"> | ||||
|                    <ion-infinite-scroll-content></ion-infinite-scroll-content> | ||||
|                 </ion-infinite-scroll> | ||||
|             </div> | ||||
|             <core-infinite-loading [enabled]="canLoadMore" (action)="showMoreActivities($event)"></core-infinite-loading> | ||||
|         </div> | ||||
|     </core-loading> | ||||
|     <ion-buttons padding end class="core-course-section-nav-buttons" *ngIf="displaySectionSelector && sections && sections.length"> | ||||
|  | ||||
| @ -373,9 +373,9 @@ export class CoreCourseFormatComponent implements OnInit, OnChanges, OnDestroy { | ||||
|     /** | ||||
|      * Show more activities (only used when showing all the sections at the same time). | ||||
|      * | ||||
|      * @return {Promise<void>} Resolved when done to change infinite loading status. | ||||
|      * @param {any} [infiniteComplete] Infinite scroll complete function. Only used from core-infinite-loading. | ||||
|      */ | ||||
|     showMoreActivities(): Promise<void> { | ||||
|     showMoreActivities(infiniteComplete?: any): void { | ||||
|         this.canLoadMore = false; | ||||
| 
 | ||||
|         let modulesLoaded = 0, | ||||
| @ -399,7 +399,7 @@ export class CoreCourseFormatComponent implements OnInit, OnChanges, OnDestroy { | ||||
|             // Check if any of the following sections have any content.
 | ||||
|             let thereAreMore = false; | ||||
|             for (i++; i < this.sections.length; i++) { | ||||
|                 if (this.sections[i].hasContent && this.sections[i].modules) { | ||||
|                 if (this.sections[i].hasContent && this.sections[i].modules && this.sections[i].modules.length > 0) { | ||||
|                     thereAreMore = true; | ||||
|                     break; | ||||
|                 } | ||||
| @ -407,7 +407,7 @@ export class CoreCourseFormatComponent implements OnInit, OnChanges, OnDestroy { | ||||
|             this.canLoadMore = thereAreMore; | ||||
|         } | ||||
| 
 | ||||
|         return Promise.resolve(); | ||||
|         infiniteComplete && infiniteComplete(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | ||||
| @ -16,7 +16,6 @@ import { Injectable } from '@angular/core'; | ||||
| import { NavController } from 'ionic-angular'; | ||||
| import { CoreCoursesProvider } from '@core/courses/providers/courses'; | ||||
| import { CoreCourseFormatHandler } from './format-delegate'; | ||||
| import { CoreCourseProvider } from './course'; | ||||
| 
 | ||||
| /** | ||||
|  * Default handler used when the course format doesn't have a specific implementation. | ||||
|  | ||||
| @ -10,12 +10,7 @@ | ||||
|         <ion-item-divider color="light">{{ 'core.courses.totalcoursesearchresults' | translate:{$a: total} }}</ion-item-divider> | ||||
|         <core-empty-box *ngIf="total == 0" icon="search" [message]="'core.courses.nosearchresults' | translate"></core-empty-box> | ||||
|         <core-courses-course-list-item *ngFor="let course of courses" [course]="course"></core-courses-course-list-item> | ||||
|         <div *ngIf="canLoadMore" padding> | ||||
|             <button ion-button block (click)="loadMoreResults()" color="light">{{'core.loadmore' | translate }}</button> | ||||
|             <ion-infinite-scroll [enabled]="canLoadMore" (ionInfinite)="loadMoreResults($event)"> | ||||
|                 <ion-infinite-scroll-content></ion-infinite-scroll-content> | ||||
|             </ion-infinite-scroll> | ||||
|         </div> | ||||
|         <core-infinite-loading [enabled]="canLoadMore" (action)="loadMoreResults($event)"></core-infinite-loading> | ||||
|     </div> | ||||
| </ion-content> | ||||
| 
 | ||||
|  | ||||
| @ -54,11 +54,11 @@ export class CoreCoursesSearchPage { | ||||
|     /** | ||||
|      * Load more results. | ||||
|      * | ||||
|      * @param {any} infiniteScroll The infinit scroll instance. | ||||
|      * @param {any} [infiniteComplete] Infinite scroll complete function. Only used from core-infinite-loading. | ||||
|      */ | ||||
|     loadMoreResults(infiniteScroll: any): void { | ||||
|     loadMoreResults(infiniteComplete?: any): void { | ||||
|         this.searchCourses().finally(() => { | ||||
|             infiniteScroll.complete(); | ||||
|             infiniteComplete && infiniteComplete(); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -16,13 +16,7 @@ | ||||
|                     <p *ngIf="participant.lastaccess"><strong>{{ 'core.lastaccess' | translate }}: </strong>{{ participant.lastaccess * 1000 | coreFormatDate:"dfmediumdate"}}</p> | ||||
|                 </a> | ||||
|             </ion-list> | ||||
| 
 | ||||
|             <div *ngIf="canLoadMore" padding> | ||||
|                 <button ion-button block (click)="fetchData()" color="light">{{'core.loadmore' | translate }}</button> | ||||
|                 <ion-infinite-scroll [enabled]="canLoadMore" (ionInfinite)="$event.waitFor(fetchData())"> | ||||
|                    <ion-infinite-scroll-content></ion-infinite-scroll-content> | ||||
|                 </ion-infinite-scroll> | ||||
|             </div> | ||||
|             <core-infinite-loading [enabled]="canLoadMore" (action)="loadMoreData($event)"></core-infinite-loading> | ||||
|         </core-loading> | ||||
|     </ion-content> | ||||
| </core-split-view> | ||||
| @ -82,6 +82,18 @@ export class CoreUserParticipantsComponent implements OnInit { | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Function to load more data. | ||||
|      * | ||||
|      * @param {any} [infiniteComplete] Infinite scroll complete function. Only used from core-infinite-loading. | ||||
|      * @return {Promise<any>} Resolved when done. | ||||
|      */ | ||||
|     loadMoreData(infiniteComplete?: any): Promise<any> { | ||||
|         return this.fetchData().finally(() => { | ||||
|             infiniteComplete && infiniteComplete(); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Refresh data. | ||||
|      * | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user