MOBILE-2877 comments: Add comments pagination
parent
dc65d4a00d
commit
797b0d7931
|
@ -14,6 +14,7 @@
|
|||
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CoreCommentsProvider } from './providers/comments';
|
||||
import { CoreEventsProvider } from '@providers/events';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
|
@ -24,4 +25,12 @@ import { CoreCommentsProvider } from './providers/comments';
|
|||
CoreCommentsProvider
|
||||
]
|
||||
})
|
||||
export class CoreCommentsModule {}
|
||||
export class CoreCommentsModule {
|
||||
constructor(eventsProvider: CoreEventsProvider) {
|
||||
// Reset comments page size.
|
||||
eventsProvider.on(CoreEventsProvider.LOGIN, () => {
|
||||
CoreCommentsProvider.pageSize = null;
|
||||
CoreCommentsProvider.pageSizeOK = false;
|
||||
});
|
||||
}
|
||||
}
|
|
@ -36,7 +36,8 @@ export class CoreCommentsCommentsComponent implements OnChanges, OnDestroy {
|
|||
@Output() onLoading: EventEmitter<boolean>; // Eevent that indicates whether the component is loading data.
|
||||
|
||||
commentsLoaded = false;
|
||||
commentsCount: number;
|
||||
commentsCount: string;
|
||||
countError = false;
|
||||
disabled = false;
|
||||
|
||||
protected updateSiteObserver;
|
||||
|
@ -84,22 +85,20 @@ export class CoreCommentsCommentsComponent implements OnChanges, OnDestroy {
|
|||
this.commentsLoaded = false;
|
||||
this.onLoading.emit(true);
|
||||
|
||||
this.commentsProvider.getComments(this.contextLevel, this.instanceId, this.component, this.itemId, this.area, this.page)
|
||||
.then((comments) => {
|
||||
this.commentsCount = comments && comments.length ? comments.length : 0;
|
||||
}).catch(() => {
|
||||
this.commentsCount = -1;
|
||||
}).finally(() => {
|
||||
this.commentsLoaded = true;
|
||||
this.onLoading.emit(false);
|
||||
});
|
||||
this.commentsProvider.getCommentsCount(this.contextLevel, this.instanceId, this.component, this.itemId, this.area)
|
||||
.then((commentsCount) => {
|
||||
this.commentsCount = commentsCount;
|
||||
this.countError = parseInt(this.commentsCount, 10) < 0;
|
||||
this.commentsLoaded = true;
|
||||
this.onLoading.emit(false);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the comments page.
|
||||
*/
|
||||
openComments(): void {
|
||||
if (!this.disabled && this.commentsCount >= 0) {
|
||||
if (!this.disabled && !this.countError) {
|
||||
// Open a new state with the interpolated contents.
|
||||
this.navCtrl.push('CoreCommentsViewerPage', {
|
||||
contextLevel: this.contextLevel,
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<core-loading *ngIf="!disabled" [hideUntil]="commentsLoaded || !displaySpinner">
|
||||
<div (click)="openComments()" *ngIf="commentsCount >= 0" [class.core-comments-clickable]="!disabled">
|
||||
<div (click)="openComments()" *ngIf="!countError" [class.core-comments-clickable]="!disabled">
|
||||
{{ 'core.comments.commentscount' | translate : {'$a': commentsCount} }}
|
||||
</div>
|
||||
<div *ngIf="commentsCount < 0">
|
||||
<div *ngIf="countError">
|
||||
{{ 'core.comments.commentsnotworking' | translate }}
|
||||
</div>
|
||||
</core-loading>
|
||||
|
|
|
@ -20,9 +20,11 @@
|
|||
<core-format-text clean="true" [text]="comment.content"></core-format-text>
|
||||
</ion-item>
|
||||
</ion-card>
|
||||
|
||||
<core-infinite-loading [enabled]="canLoadMore" (action)="loadMore($event)" [error]="loadMoreError"></core-infinite-loading>
|
||||
</core-loading>
|
||||
|
||||
<ion-fab core-fab bottom end *ngIf="addCommentsAvailable">
|
||||
<ion-fab core-fab bottom end *ngIf="canAddComments">
|
||||
<button ion-fab (click)="addComment()" [attr.aria-label]="'core.comments.addcomment' | translate">
|
||||
<ion-icon name="add"></ion-icon>
|
||||
</button>
|
||||
|
|
|
@ -40,7 +40,11 @@ export class CoreCommentsViewerPage {
|
|||
area: string;
|
||||
page: number;
|
||||
title: string;
|
||||
addCommentsAvailable = false;
|
||||
canLoadMore = false;
|
||||
loadMoreError = false;
|
||||
canAddComments = false;
|
||||
|
||||
protected addCommentsAvailable = false;
|
||||
|
||||
constructor(navParams: NavParams, sitesProvider: CoreSitesProvider, private userProvider: CoreUserProvider,
|
||||
private domUtils: CoreDomUtilsProvider, private translate: TranslateService,
|
||||
|
@ -74,11 +78,16 @@ export class CoreCommentsViewerPage {
|
|||
* @return {Promise<any>} Resolved when done.
|
||||
*/
|
||||
protected fetchComments(): Promise<any> {
|
||||
this.loadMoreError = false;
|
||||
|
||||
// Get comments data.
|
||||
return this.commentsProvider.getComments(this.contextLevel, this.instanceId, this.component, this.itemId,
|
||||
this.area, this.page).then((comments) => {
|
||||
this.comments = comments;
|
||||
this.comments.sort((a, b) => b.timecreated - a.timecreated);
|
||||
this.area, this.page).then((response) => {
|
||||
this.canAddComments = this.addCommentsAvailable && response.canpost;
|
||||
|
||||
const comments = response.comments.sort((a, b) => b.timecreated - a.timecreated);
|
||||
this.canLoadMore = comments.length >= CoreCommentsProvider.pageSize;
|
||||
|
||||
this.comments.forEach((comment) => {
|
||||
// Get the user profile image.
|
||||
this.userProvider.getProfile(comment.userid, undefined, true).then((user) => {
|
||||
|
@ -87,7 +96,11 @@ export class CoreCommentsViewerPage {
|
|||
// Ignore errors.
|
||||
});
|
||||
});
|
||||
|
||||
this.comments = this.comments.concat(comments);
|
||||
|
||||
}).catch((error) => {
|
||||
this.loadMoreError = true; // Set to prevent infinite calls with infinite-loading.
|
||||
if (error && this.component == 'assignsubmission_comments') {
|
||||
this.domUtils.showAlertTranslated('core.notice', 'core.comments.commentsnotworking');
|
||||
} else {
|
||||
|
@ -96,6 +109,21 @@ export class CoreCommentsViewerPage {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to load more cp,,emts.
|
||||
*
|
||||
* @param {any} [infiniteComplete] Infinite scroll complete function. Only used from core-infinite-loading.
|
||||
* @return {Promise<any>} Resolved when done.
|
||||
*/
|
||||
loadMore(infiniteComplete?: any): Promise<any> {
|
||||
this.page++;
|
||||
this.canLoadMore = false;
|
||||
|
||||
return this.fetchComments().finally(() => {
|
||||
infiniteComplete && infiniteComplete();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh the comments.
|
||||
*
|
||||
|
@ -103,7 +131,10 @@ export class CoreCommentsViewerPage {
|
|||
*/
|
||||
refreshComments(refresher: any): void {
|
||||
this.commentsProvider.invalidateCommentsData(this.contextLevel, this.instanceId, this.component,
|
||||
this.itemId, this.area, this.page).finally(() => {
|
||||
this.itemId, this.area).finally(() => {
|
||||
this.page = 0;
|
||||
this.comments = [];
|
||||
|
||||
return this.fetchComments().finally(() => {
|
||||
refresher.complete();
|
||||
});
|
||||
|
|
|
@ -23,6 +23,8 @@ import { CoreSite } from '@classes/site';
|
|||
export class CoreCommentsProvider {
|
||||
|
||||
protected ROOT_CACHE_KEY = 'mmComments:';
|
||||
static pageSize = null;
|
||||
static pageSizeOK = false; // If true, the pageSize is definitive. If not, it's a temporal value to reduce WS calls.
|
||||
|
||||
constructor(private sitesProvider: CoreSitesProvider) {}
|
||||
|
||||
|
@ -125,7 +127,7 @@ export class CoreCommentsProvider {
|
|||
|
||||
return site.read('core_comment_get_comments', params, preSets).then((response) => {
|
||||
if (response.comments) {
|
||||
return response.comments;
|
||||
return response;
|
||||
}
|
||||
|
||||
return Promise.reject(null);
|
||||
|
@ -133,6 +135,62 @@ export class CoreCommentsProvider {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get comments count number to show ont he comments component.
|
||||
*
|
||||
* @param {string} contextLevel Contextlevel system, course, user...
|
||||
* @param {number} instanceId The Instance id of item associated with the context level.
|
||||
* @param {string} component Component name.
|
||||
* @param {number} itemId Associated id.
|
||||
* @param {string} [area=''] String comment area. Default empty.
|
||||
* @param {string} [siteId] Site ID. If not defined, current site.
|
||||
* @return {Promise<string>} Comments count with plus sign if needed.
|
||||
*/
|
||||
getCommentsCount(contextLevel: string, instanceId: number, component: string, itemId: number, area: string = '',
|
||||
siteId?: string): Promise<string> {
|
||||
|
||||
siteId = siteId ? siteId : this.sitesProvider.getCurrentSiteId();
|
||||
|
||||
// Convenience function to get comments number on a page.
|
||||
const getCommentsPageCount = (page: number): Promise<number> => {
|
||||
return this.getComments(contextLevel, instanceId, component, itemId, area, page, siteId).then((response) => {
|
||||
if (response.comments) {
|
||||
// Update pageSize with the greatest count at the moment.
|
||||
if (response.comments && response.comments.length > CoreCommentsProvider.pageSize) {
|
||||
CoreCommentsProvider.pageSize = response.comments.length;
|
||||
}
|
||||
|
||||
return response.comments && response.comments.length ? response.comments.length : 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}).catch(() => {
|
||||
return -1;
|
||||
});
|
||||
};
|
||||
|
||||
return getCommentsPageCount(0).then((count) => {
|
||||
if (CoreCommentsProvider.pageSizeOK && count >= CoreCommentsProvider.pageSize) {
|
||||
// Page Size is ok, show + in case it reached the limit.
|
||||
return (CoreCommentsProvider.pageSize - 1) + '+';
|
||||
} else if (count < 0 || (CoreCommentsProvider.pageSize && count < CoreCommentsProvider.pageSize)) {
|
||||
return count + '';
|
||||
}
|
||||
|
||||
// Call to update page size.
|
||||
return getCommentsPageCount(1).then((countMore) => {
|
||||
// Page limit was reached on the previous call.
|
||||
if (countMore > 0) {
|
||||
CoreCommentsProvider.pageSizeOK = true;
|
||||
|
||||
return (CoreCommentsProvider.pageSize - 1) + '+';
|
||||
}
|
||||
|
||||
return count + '';
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidates comments data.
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue