forked from EVOgeek/Vmeda.Online
		
	MOBILE-2877 comments: Delete comments
This commit is contained in:
		
							parent
							
								
									79bdd4ed02
								
							
						
					
					
						commit
						8a56dc84b8
					
				| @ -169,11 +169,13 @@ export class AddonBlogEntriesComponent implements OnInit { | ||||
|      * @param {any}     refresher  Refresher instance. | ||||
|      */ | ||||
|     refresh(refresher?: any): void { | ||||
|         this.entries.forEach((entry) => { | ||||
|             this.commentsProvider.invalidateCommentsData('user', entry.userid, this.component, entry.id, 'format_blog'); | ||||
|         const promises = this.entries.map((entry) => { | ||||
|             return this.commentsProvider.invalidateCommentsData('user', entry.userid, this.component, entry.id, 'format_blog'); | ||||
|         }); | ||||
| 
 | ||||
|         this.blogProvider.invalidateEntries(this.filter).finally(() => { | ||||
|         promises.push(this.blogProvider.invalidateEntries(this.filter)); | ||||
| 
 | ||||
|         Promise.all(promises).finally(() => { | ||||
|             this.fetchEntries(true).finally(() => { | ||||
|                 if (refresher) { | ||||
|                     refresher.complete(); | ||||
|  | ||||
| @ -1269,9 +1269,12 @@ | ||||
|     "core.comments.comments": "Comments", | ||||
|     "core.comments.commentscount": "Comments ({{$a}})", | ||||
|     "core.comments.commentsnotworking": "Comments cannot be retrieved", | ||||
|     "core.comments.deletecommentbyon": "Delete comment posted by {{$a.user}} on {{$a.time}}", | ||||
|     "core.comments.eventcommentcreated": "Comment created", | ||||
|     "core.comments.eventcommentdeleted": "Comment deleted", | ||||
|     "core.comments.nocomments": "No comments", | ||||
|     "core.comments.savecomment": "Save comment", | ||||
|     "core.comments.warningcommentsnotsent": "Couldn't sync comments. {{error}}", | ||||
|     "core.completion-alt-auto-fail": "Completed: {{$a}} (did not achieve pass grade)", | ||||
|     "core.completion-alt-auto-n": "Not completed: {{$a}}", | ||||
|     "core.completion-alt-auto-n-override": "Not completed: {{$a.modname}} (set by {{$a.overrideuser}})", | ||||
|  | ||||
| @ -3,7 +3,10 @@ | ||||
|     "comments": "Comments", | ||||
|     "commentscount": "Comments ({{$a}})", | ||||
|     "commentsnotworking": "Comments cannot be retrieved", | ||||
|     "deletecommentbyon": "Delete comment posted by {{$a.user}} on {{$a.time}}", | ||||
|     "eventcommentcreated": "Comment created", | ||||
|     "eventcommentdeleted": "Comment deleted", | ||||
|     "nocomments": "No comments", | ||||
|     "savecomment": "Save comment" | ||||
|     "savecomment": "Save comment", | ||||
|     "warningcommentsnotsent": "Couldn't sync comments. {{error}}" | ||||
| } | ||||
| @ -57,7 +57,7 @@ export class CoreCommentsAddPage { | ||||
| 
 | ||||
|         this.appProvider.closeKeyboard(); | ||||
|         const loadingModal = this.domUtils.showModalLoading('core.sending', true); | ||||
|         // Freeze the add note button.
 | ||||
|         // Freeze the add comment button.
 | ||||
|         this.processing = true; | ||||
|         this.commentsProvider.addComment(this.content, this.contextLevel, this.instanceId, this.componentName, this.itemId, | ||||
|                 this.area).then((commentsResponse) => { | ||||
|  | ||||
| @ -2,6 +2,9 @@ | ||||
|     <ion-navbar core-back-button> | ||||
|         <ion-title><core-format-text [text]="title"></core-format-text></ion-title> | ||||
|         <ion-buttons end> | ||||
|             <button *ngIf="canDeleteComments" item-end ion-button icon-only clear (click)="toggleDelete($event)" [attr.aria-label]="'core.delete' | translate"> | ||||
|                 <ion-icon name="create" ios="md-create"></ion-icon> | ||||
|             </button> | ||||
|             <core-context-menu> | ||||
|                 <core-context-menu-item [hidden]="!(commentsLoaded && !hasOffline)" [priority]="100" [content]="'core.refresh' | translate" (action)="refreshComments(false)" [iconAction]="refreshIcon" [closeOnClick]="true"></core-context-menu-item> | ||||
|                 <core-context-menu-item [hidden]="!(commentsLoaded && hasOffline)" [priority]="100" [content]="'core.settings.synchronizenow' | translate" (action)="refreshComments(true)" [iconAction]="syncIcon" [closeOnClick]="false"></core-context-menu-item> | ||||
| @ -21,13 +24,16 @@ | ||||
|             {{ 'core.thereisdatatosync' | translate:{$a: 'core.comments.comments' | translate | lowercase } }} | ||||
|         </div> | ||||
| 
 | ||||
|         <ion-card *ngIf="hasOffline" (click)="addComment($event)"> | ||||
|         <ion-card *ngIf="offlineComment" (click)="addComment($event)"> | ||||
|             <ion-item text-wrap> | ||||
|                 <ion-avatar core-user-avatar [user]="offlineComment" item-start></ion-avatar> | ||||
|                 <h2>{{ offlineComment.fullname }}</h2> | ||||
|                 <p> | ||||
|                     <ion-icon name="time"></ion-icon> {{ 'core.notsent' | translate }} | ||||
|                 </p> | ||||
|                 <button *ngIf="showDelete" item-end ion-button icon-only clear [@coreSlideInOut]="'fromRight'" color="danger" (click)="deleteComment($event, offlineComment)" [attr.aria-label]="'core.delete' | translate"> | ||||
|                     <ion-icon name="trash"></ion-icon> | ||||
|                 </button> | ||||
|             </ion-item> | ||||
|             <ion-item text-wrap> | ||||
|                 <core-format-text clean="true" [text]="offlineComment.content"></core-format-text> | ||||
| @ -38,7 +44,16 @@ | ||||
|             <ion-item text-wrap> | ||||
|                 <ion-avatar core-user-avatar [user]="comment" item-start></ion-avatar> | ||||
|                 <h2>{{ comment.fullname }}</h2> | ||||
|                 <p>{{ comment.timecreated * 1000 | coreFormatDate: 'strftimerecentfull' }}</p> | ||||
|                 <p *ngIf="!comment.deleted">{{ comment.timecreated * 1000 | coreFormatDate: 'strftimerecentfull' }}</p> | ||||
|                 <p *ngIf="comment.deleted"> | ||||
|                     <ion-icon name="trash"></ion-icon> <span text-wrap>{{ 'core.deletedoffline' | translate }}</span> | ||||
|                 </p> | ||||
|                 <button *ngIf="showDelete && !comment.deleted && comment.delete" item-end ion-button icon-only clear [@coreSlideInOut]="'fromRight'" color="danger" (click)="deleteComment($event, comment)" [attr.aria-label]="'core.delete' | translate"> | ||||
|                     <ion-icon name="trash"></ion-icon> | ||||
|                 </button> | ||||
|                 <button *ngIf="showDelete && comment.deleted" item-end ion-button icon-only clear color="danger" (click)="undoDeleteComment($event, comment)" [attr.aria-label]="'core.restore' | translate"> | ||||
|                     <ion-icon name="undo"></ion-icon> | ||||
|                 </button> | ||||
|             </ion-item> | ||||
|             <ion-item text-wrap> | ||||
|                 <core-format-text clean="true" [text]="comment.content"></core-format-text> | ||||
|  | ||||
| @ -15,9 +15,11 @@ | ||||
| import { Component, ViewChild, OnDestroy } from '@angular/core'; | ||||
| import { IonicPage, Content, NavParams, ModalController } from 'ionic-angular'; | ||||
| import { TranslateService } from '@ngx-translate/core'; | ||||
| import { coreSlideInOut } from '@classes/animations'; | ||||
| import { CoreSitesProvider } from '@providers/sites'; | ||||
| import { CoreDomUtilsProvider } from '@providers/utils/dom'; | ||||
| import { CoreTextUtilsProvider } from '@providers/utils/text'; | ||||
| import { CoreTimeUtilsProvider } from '@providers/utils/time'; | ||||
| import { CoreEventsProvider } from '@providers/events'; | ||||
| import { CoreUserProvider } from '@core/user/providers/user'; | ||||
| import { CoreCommentsProvider } from '../../providers/comments'; | ||||
| @ -31,6 +33,7 @@ import { CoreCommentsSyncProvider } from '../../providers/sync'; | ||||
| @Component({ | ||||
|     selector: 'page-core-comments-viewer', | ||||
|     templateUrl: 'viewer.html', | ||||
|     animations: [coreSlideInOut] | ||||
| }) | ||||
| export class CoreCommentsViewerPage implements OnDestroy { | ||||
|     @ViewChild(Content) content: Content; | ||||
| @ -47,12 +50,15 @@ export class CoreCommentsViewerPage implements OnDestroy { | ||||
|     canLoadMore = false; | ||||
|     loadMoreError = false; | ||||
|     canAddComments = false; | ||||
|     canDeleteComments = false; | ||||
|     showDelete = false; | ||||
|     hasOffline = false; | ||||
|     refreshIcon = 'spinner'; | ||||
|     syncIcon = 'spinner'; | ||||
|     offlineComment: any; | ||||
|     currentUserId: number; | ||||
| 
 | ||||
|     protected addCommentsAvailable = false; | ||||
|     protected addDeleteCommentsAvailable = false; | ||||
|     protected syncObserver: any; | ||||
|     protected currentUser: any; | ||||
| 
 | ||||
| @ -60,7 +66,7 @@ export class CoreCommentsViewerPage implements OnDestroy { | ||||
|              private domUtils: CoreDomUtilsProvider, private translate: TranslateService, private modalCtrl: ModalController, | ||||
|              private commentsProvider: CoreCommentsProvider, private offlineComments: CoreCommentsOfflineProvider, | ||||
|              eventsProvider: CoreEventsProvider, private commentsSync: CoreCommentsSyncProvider, | ||||
|              private textUtils: CoreTextUtilsProvider) { | ||||
|              private textUtils: CoreTextUtilsProvider, private timeUtils: CoreTimeUtilsProvider) { | ||||
| 
 | ||||
|         this.contextLevel = navParams.get('contextLevel'); | ||||
|         this.instanceId = navParams.get('instanceId'); | ||||
| @ -96,34 +102,35 @@ export class CoreCommentsViewerPage implements OnDestroy { | ||||
|      */ | ||||
|     ionViewDidLoad(): void { | ||||
|         this.commentsProvider.isAddCommentsAvailable().then((enabled) => { | ||||
|             this.addCommentsAvailable = enabled; | ||||
|             // Is implicit the user can delete if he can add.
 | ||||
|             this.addDeleteCommentsAvailable = enabled; | ||||
|         }); | ||||
| 
 | ||||
|         this.currentUserId = this.sitesProvider.getCurrentSiteUserId(); | ||||
|         this.fetchComments(true); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Fetches the comments. | ||||
|      * | ||||
|      * @param  {boolean} sync         When to resync notes. | ||||
|      * @param  {boolean} sync         When to resync comments. | ||||
|      * @param  {boolean} [showErrors] When to display errors or not. | ||||
|      * @return {Promise<any>} Resolved when done. | ||||
|      */ | ||||
|     protected fetchComments(sync: boolean, showErrors?: boolean): Promise<any> { | ||||
|         this.loadMoreError = false; | ||||
| 
 | ||||
|         const promise = sync ? this.syncComment(showErrors) : Promise.resolve(); | ||||
|         const promise = sync ? this.syncComments(showErrors) : Promise.resolve(); | ||||
| 
 | ||||
|         return promise.catch(() => { | ||||
|             // Ignore errors.
 | ||||
|         }).then(() => { | ||||
|             return this.offlineComments.getComment(this.contextLevel, this.instanceId, this.componentName, this.itemId, | ||||
|                     this.area).then((offlineComment) => { | ||||
|                 this.hasOffline = !!offlineComment; | ||||
|                 this.offlineComment = offlineComment; | ||||
| 
 | ||||
|                 if (this.hasOffline && !this.currentUser) { | ||||
|                     return this.userProvider.getProfile(this.sitesProvider.getCurrentSiteUserId(), undefined, true).then((user) => { | ||||
|                 if (offlineComment && !this.currentUser) { | ||||
|                     return this.userProvider.getProfile(this.currentUserId, undefined, true).then((user) => { | ||||
|                         this.currentUser = user; | ||||
|                         this.offlineComment.profileimageurl = user.profileimageurl; | ||||
|                         this.offlineComment.fullname = user.fullname; | ||||
| @ -131,32 +138,53 @@ export class CoreCommentsViewerPage implements OnDestroy { | ||||
|                     }).catch(() => { | ||||
|                         // Ignore errors.
 | ||||
|                     }); | ||||
|                 } else if (this.hasOffline) { | ||||
|                 } else if (offlineComment) { | ||||
|                     this.offlineComment.profileimageurl = this.currentUser.profileimageurl; | ||||
|                     this.offlineComment.fullname = this.currentUser.fullname; | ||||
|                     this.offlineComment.userid = this.currentUser.id; | ||||
|                 } | ||||
| 
 | ||||
|                 return this.offlineComments.getDeletedComments(this.contextLevel, this.instanceId, this.componentName, this.itemId, | ||||
|                     this.area); | ||||
|             }); | ||||
|         }).then(() => { | ||||
|         }).then((deletedComments) => { | ||||
|             this.hasOffline = !!this.offlineComment || deletedComments.length > 0; | ||||
| 
 | ||||
|             // Get comments data.
 | ||||
|             return this.commentsProvider.getComments(this.contextLevel, this.instanceId, this.componentName, this.itemId, | ||||
|                     this.area, this.page).then((response) => { | ||||
|                 this.canAddComments = this.addCommentsAvailable && response.canpost; | ||||
|                 this.canAddComments = this.addDeleteCommentsAvailable && response.canpost; | ||||
| 
 | ||||
|                 const comments = response.comments.sort((a, b) => b.timecreated - a.timecreated); | ||||
|                 this.canLoadMore = comments.length >= CoreCommentsProvider.pageSize; | ||||
| 
 | ||||
|                 this.comments.forEach((comment) => { | ||||
|                 return Promise.all(comments.map((comment) => { | ||||
|                     // Get the user profile image.
 | ||||
|                     this.userProvider.getProfile(comment.userid, undefined, true).then((user) => { | ||||
|                     return this.userProvider.getProfile(comment.userid, undefined, true).then((user) => { | ||||
|                         comment.profileimageurl = user.profileimageurl; | ||||
| 
 | ||||
|                         return comment; | ||||
|                     }).catch(() => { | ||||
|                         // Ignore errors.
 | ||||
|                         return comment; | ||||
|                     }); | ||||
|                 })); | ||||
|             }).then((comments) => { | ||||
|                 this.comments = this.comments.concat(comments); | ||||
| 
 | ||||
|                 deletedComments && deletedComments.forEach((deletedComment) => { | ||||
|                     const comment = this.comments.find((comment) => { | ||||
|                         return comment.id == deletedComment.commentid; | ||||
|                     }); | ||||
| 
 | ||||
|                     if (comment) { | ||||
|                         comment.deleted = deletedComment.deleted; | ||||
|                     } | ||||
|                 }); | ||||
| 
 | ||||
|                 this.comments = this.comments.concat(comments); | ||||
|                 this.canDeleteComments = this.addDeleteCommentsAvailable && (this.hasOffline || this.comments.some((comment) => { | ||||
|                     return !!comment.delete; | ||||
|                 })); | ||||
|             }); | ||||
|         }).catch((error) => { | ||||
|             this.loadMoreError = true; // Set to prevent infinite calls with infinite-loading.
 | ||||
| @ -174,7 +202,7 @@ export class CoreCommentsViewerPage implements OnDestroy { | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Function to load more cp,,emts. | ||||
|      * Function to load more commemts. | ||||
|      * | ||||
|      * @param {any} [infiniteComplete] Infinite scroll complete function. Only used from core-infinite-loading. | ||||
|      * @return {Promise<any>} Resolved when done. | ||||
| @ -228,8 +256,8 @@ export class CoreCommentsViewerPage implements OnDestroy { | ||||
|      * @param  {boolean} showErrors Whether to display errors or not. | ||||
|      * @return {Promise<any>}       Promise resolved if sync is successful, rejected otherwise. | ||||
|      */ | ||||
|     private syncComment(showErrors: boolean): Promise<any> { | ||||
|         return this.commentsSync.syncComment(this.contextLevel, this.instanceId, this.componentName, this.itemId, | ||||
|     private syncComments(showErrors: boolean): Promise<any> { | ||||
|         return this.commentsSync.syncComments(this.contextLevel, this.instanceId, this.componentName, this.itemId, | ||||
|                 this.area).then((warnings) => { | ||||
|             this.showSyncWarnings(warnings); | ||||
|         }).catch((error) => { | ||||
| @ -263,6 +291,7 @@ export class CoreCommentsViewerPage implements OnDestroy { | ||||
|         modal.onDidDismiss((data) => { | ||||
|             if (data && data.comments) { | ||||
|                 this.comments = data.comments.concat(this.comments); | ||||
|                 this.canDeleteComments = this.addDeleteCommentsAvailable; | ||||
|             } else if (data && !data.comments) { | ||||
|                 this.fetchComments(false); | ||||
|             } | ||||
| @ -270,6 +299,63 @@ export class CoreCommentsViewerPage implements OnDestroy { | ||||
|         modal.present(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Delete a comment. | ||||
|      * | ||||
|      * @param {Event} e     Click event. | ||||
|      * @param {any} comment Comment to delete. | ||||
|      */ | ||||
|     deleteComment(e: Event, comment: any): void { | ||||
|         e.preventDefault(); | ||||
|         e.stopPropagation(); | ||||
| 
 | ||||
|         const time = this.timeUtils.userDate((comment.lastmodified || comment.timecreated) * 1000, 'core.strftimerecentfull'); | ||||
| 
 | ||||
|         comment.contextlevel = this.contextLevel; | ||||
|         comment.instanceid = this.instanceId; | ||||
|         comment.component = this.componentName; | ||||
|         comment.itemid = this.itemId; | ||||
|         comment.area = this.area; | ||||
| 
 | ||||
|         this.domUtils.showConfirm(this.translate.instant('core.comments.deletecommentbyon', {$a: | ||||
|                 { user: comment.fullname || '', time: time } })).then(() => { | ||||
|             this.commentsProvider.deleteComment(comment).then(() => { | ||||
|                 this.showDelete = false; | ||||
| 
 | ||||
|                 this.refreshComments(true); | ||||
| 
 | ||||
|                 this.domUtils.showToast('core.comments.eventcommentdeleted', true, 3000); | ||||
|             }).catch((error) => { | ||||
|                 this.domUtils.showErrorModalDefault(error, 'Delete comment failed.'); | ||||
|             }); | ||||
|         }).catch(() => { | ||||
|             // User cancelled, nothing to do.
 | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Restore a comment. | ||||
|      * | ||||
|      * @param {Event} e Click event. | ||||
|      * @param {any} comment Comment to delete. | ||||
|      */ | ||||
|     undoDeleteComment(e: Event, comment: any): void { | ||||
|         e.preventDefault(); | ||||
|         e.stopPropagation(); | ||||
| 
 | ||||
|         this.offlineComments.undoDeleteComment(comment.id).then(() => { | ||||
|             comment.deleted = false; | ||||
|             this.showDelete = false; | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Toggle delete. | ||||
|      */ | ||||
|     toggleDelete(): void { | ||||
|         this.showDelete = !this.showDelete; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Page destroyed. | ||||
|      */ | ||||
|  | ||||
| @ -48,7 +48,7 @@ export class CoreCommentsProvider { | ||||
|             siteId?: string): Promise<boolean> { | ||||
|         siteId = siteId || this.sitesProvider.getCurrentSiteId(); | ||||
| 
 | ||||
|         // Convenience function to store a note to be synchronized later.
 | ||||
|         // Convenience function to store a comment to be synchronized later.
 | ||||
|         const storeOffline = (): Promise<any> => { | ||||
|             return this.commentsOffline.saveComment(content, contextLevel, instanceId, component, itemId, area, siteId).then(() => { | ||||
|                 return Promise.resolve(false); | ||||
| @ -56,11 +56,11 @@ export class CoreCommentsProvider { | ||||
|         }; | ||||
| 
 | ||||
|         if (!this.appProvider.isOnline()) { | ||||
|             // App is offline, store the note.
 | ||||
|             // App is offline, store the comment.
 | ||||
|             return storeOffline(); | ||||
|         } | ||||
| 
 | ||||
|         // Send note to server.
 | ||||
|         // Send comment to server.
 | ||||
|         return this.addCommentOnline(content, contextLevel, instanceId, component, itemId, area, siteId).then((comments) => { | ||||
|             return comments; | ||||
|         }).catch((error) => { | ||||
| @ -69,7 +69,7 @@ export class CoreCommentsProvider { | ||||
|                 return Promise.reject(error); | ||||
|             } | ||||
| 
 | ||||
|             // Error sending note, store it to retry later.
 | ||||
|             // Error sending comment, store it to retry later.
 | ||||
|             return storeOffline(); | ||||
|         }); | ||||
|     } | ||||
| @ -115,7 +115,7 @@ export class CoreCommentsProvider { | ||||
|      * @param  {any[]}  comments Comments to save. | ||||
|      * @param  {string} [siteId] Site ID. If not defined, current site. | ||||
|      * @return {Promise<any>}    Promise resolved when added, rejected otherwise. Promise resolved doesn't mean that comments | ||||
|      *                           have been added, the resolve param can contain errors for notes not sent. | ||||
|      *                           have been added, the resolve param can contain errors for comments not sent. | ||||
|      */ | ||||
|     addCommentsOnline(comments: any[], siteId?: string): Promise<any> { | ||||
|         if (!comments || !comments.length) { | ||||
| @ -155,6 +155,79 @@ export class CoreCommentsProvider { | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Delete a comment. | ||||
|      * | ||||
|      * @param  {any} comment         Comment object to delete. | ||||
|      * @param  {string} [siteId]     Site ID. If not defined, current site. | ||||
|      * @return {Promise<void>}       Promise resolved when deleted, rejected otherwise. Promise resolved doesn't mean that comments | ||||
|      *                               have been deleted, the resolve param can contain errors for comments not deleted. | ||||
|      */ | ||||
|     deleteComment(comment: any, siteId?: string): Promise<void> { | ||||
|         siteId = siteId || this.sitesProvider.getCurrentSiteId(); | ||||
| 
 | ||||
|         if (!comment.id) { | ||||
|             return this.commentsOffline.removeComment(comment.contextlevel, comment.instanceid, comment.component, comment.itemid, | ||||
|                     comment.area, siteId); | ||||
|         } | ||||
| 
 | ||||
|         // Convenience function to store the action to be synchronized later.
 | ||||
|         const storeOffline = (): Promise<any> => { | ||||
|             return this.commentsOffline.deleteComment(comment.id, comment.contextlevel, comment.instanceid, comment.component, | ||||
|                     comment.itemid, comment.area, siteId).then(() => { | ||||
|                 return false; | ||||
|             }); | ||||
|         }; | ||||
| 
 | ||||
|         if (!this.appProvider.isOnline()) { | ||||
|             // App is offline, store the comment.
 | ||||
|             return storeOffline(); | ||||
|         } | ||||
| 
 | ||||
|         // Send comment to server.
 | ||||
|         return this.deleteCommentsOnline([comment.id], comment.contextlevel, comment.instanceid, comment.component, comment.itemid, | ||||
|                 comment.area, siteId).then(() => { | ||||
|             return true; | ||||
|         }).catch((error) => { | ||||
|             if (this.utils.isWebServiceError(error)) { | ||||
|                 // It's a WebService error, the user cannot send the comment so don't store it.
 | ||||
|                 return Promise.reject(error); | ||||
|             } | ||||
| 
 | ||||
|             // Error sending comment, store it to retry later.
 | ||||
|             return storeOffline(); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Delete a comment. It will fail if offline or cannot connect. | ||||
|      * | ||||
|      * @param  {number[]} commentIds Comment IDs to delete. | ||||
|      * @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<void>}       Promise resolved when deleted, rejected otherwise. Promise resolved doesn't mean that comments | ||||
|      *                               have been deleted, the resolve param can contain errors for comments not deleted. | ||||
|      */ | ||||
|     deleteCommentsOnline(commentIds: number[], contextLevel: string, instanceId: number, component: string, itemId: number, | ||||
|             area: string = '', siteId?: string): Promise<void> { | ||||
|         return this.sitesProvider.getSite(siteId).then((site) => { | ||||
|             const data = { | ||||
|                 comments: commentIds | ||||
|             }; | ||||
| 
 | ||||
|             return site.write('core_comment_delete_comments', data).then((response) => { | ||||
|                 // A comment was deleted, invalidate comments.
 | ||||
|                 return this.invalidateCommentsData(contextLevel, instanceId, component, itemId, area, siteId).catch(() => { | ||||
|                     // Ignore errors.
 | ||||
|                 }); | ||||
|             }); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Returns whether WS to add/delete comments are available in site. | ||||
|      * | ||||
| @ -239,7 +312,7 @@ export class CoreCommentsProvider { | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Get comments count number to show ont he comments component. | ||||
|      * Get comments count number to show on the comments component. | ||||
|      * | ||||
|      * @param  {string} contextLevel Contextlevel system, course, user... | ||||
|      * @param  {number} instanceId   The Instance id of item associated with the context level. | ||||
| @ -284,7 +357,6 @@ export class CoreCommentsProvider { | ||||
|             return getCommentsPageCount(1).then((countMore) => { | ||||
|                 // Page limit was reached on the previous call.
 | ||||
|                 if (countMore > 0) { | ||||
|                     CoreCommentsProvider.pageSizeOK = true; | ||||
| 
 | ||||
|                     return (CoreCommentsProvider.pageSize - 1) + '+'; | ||||
|                 } | ||||
| @ -308,11 +380,14 @@ export class CoreCommentsProvider { | ||||
|     invalidateCommentsData(contextLevel: string, instanceId: number, component: string, itemId: number, | ||||
|             area: string = '', siteId?: string): Promise<any> { | ||||
|         return this.sitesProvider.getSite(siteId).then((site) => { | ||||
|             // This is done with starting with to avoid conflicts with previous keys that were including page.
 | ||||
|             site.invalidateWsCacheForKeyStartingWith(this.getCommentsCacheKey(contextLevel, instanceId, component, itemId, | ||||
|                 area) + ':'); | ||||
| 
 | ||||
|             return site.invalidateWsCacheForKey(this.getCommentsCacheKey(contextLevel, instanceId, component, itemId, area)); | ||||
|             return this.utils.allPromises([ | ||||
|                 // This is done with starting with to avoid conflicts with previous keys that were including page.
 | ||||
|                 site.invalidateWsCacheForKeyStartingWith(this.getCommentsCacheKey(contextLevel, instanceId, component, itemId, | ||||
|                     area) + ':'), | ||||
| 
 | ||||
|                 site.invalidateWsCacheForKey(this.getCommentsCacheKey(contextLevel, instanceId, component, itemId, area)) | ||||
|             ]); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -24,6 +24,7 @@ export class CoreCommentsOfflineProvider { | ||||
| 
 | ||||
|     // Variables for database.
 | ||||
|     static COMMENTS_TABLE = 'core_comments_offline_comments'; | ||||
|     static COMMENTS_DELETED_TABLE = 'core_comments_deleted_offline_comments'; | ||||
|     protected siteSchema: CoreSiteSchema = { | ||||
|         name: 'CoreCommentsOfflineProvider', | ||||
|         version: 1, | ||||
| @ -55,16 +56,46 @@ export class CoreCommentsOfflineProvider { | ||||
|                         name: 'content', | ||||
|                         type: 'TEXT' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'action', | ||||
|                         type: 'TEXT' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'lastmodified', | ||||
|                         type: 'INTEGER' | ||||
|                     } | ||||
|                 ], | ||||
|                 primaryKeys: ['contextlevel', 'instanceid', 'component', 'itemid', 'area'] | ||||
|             }, | ||||
|             { | ||||
|                 name: CoreCommentsOfflineProvider.COMMENTS_DELETED_TABLE, | ||||
|                 columns: [ | ||||
|                     { | ||||
|                         name: 'commentid', | ||||
|                         type: 'INTEGER', | ||||
|                         primaryKey: true | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'contextlevel', | ||||
|                         type: 'TEXT' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'instanceid', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'component', | ||||
|                         type: 'TEXT', | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'itemid', | ||||
|                         type: 'INTEGER' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'area', | ||||
|                         type: 'TEXT' | ||||
|                     }, | ||||
|                     { | ||||
|                         name: 'deleted', | ||||
|                         type: 'INTEGER' | ||||
|                     } | ||||
|                 ] | ||||
|             } | ||||
|         ] | ||||
|     }; | ||||
| @ -73,30 +104,6 @@ export class CoreCommentsOfflineProvider { | ||||
|         this.sitesProvider.registerSiteSchema(this.siteSchema); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Delete a comment. | ||||
|      * | ||||
|      * @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<any>}       Promise resolved if deleted, rejected if failure. | ||||
|      */ | ||||
|     removeComment(contextLevel: string, instanceId: number, component: string, itemId: number, area: string = '', | ||||
|             siteId?: string): Promise<any> { | ||||
|         return this.sitesProvider.getSite(siteId).then((site) => { | ||||
|             return site.getDb().deleteRecords(CoreCommentsOfflineProvider.COMMENTS_TABLE, { | ||||
|                 contextlevel: contextLevel, | ||||
|                 instanceid: instanceId, | ||||
|                 component: component, | ||||
|                 itemid: itemId, | ||||
|                 area: area | ||||
|             }); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Get all offline comments. | ||||
|      * | ||||
| @ -105,7 +112,10 @@ export class CoreCommentsOfflineProvider { | ||||
|      */ | ||||
|     getAllComments(siteId?: string): Promise<any> { | ||||
|         return this.sitesProvider.getSite(siteId).then((site) => { | ||||
|             return site.getDb().getRecords(CoreCommentsOfflineProvider.COMMENTS_TABLE); | ||||
|             return Promise.all([site.getDb().getRecords(CoreCommentsOfflineProvider.COMMENTS_TABLE), | ||||
|                 site.getDb().getRecords(CoreCommentsOfflineProvider.COMMENTS_DELETED_TABLE)]).then((results) => { | ||||
|                     return [].concat.apply([], results); | ||||
|                 }); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
| @ -136,19 +146,116 @@ export class CoreCommentsOfflineProvider { | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Check if there are offline comments. | ||||
|      * Get all offline comments added or deleted of a special area. | ||||
|      * | ||||
|      * @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. | ||||
|      * @return {Promise<boolean>} Promise resolved with boolean: true if has offline comments, false otherwise. | ||||
|      * @param  {string} [siteId]    Site ID. If not defined, current site. | ||||
|      * @return {Promise<any>}       Promise resolved with the comments. | ||||
|      */ | ||||
|     hasComments(contextLevel: string, instanceId: number, component: string, itemId: number, area: string = '', | ||||
|             siteId?: string): Promise<boolean> { | ||||
|         return this.getComment(contextLevel, instanceId, component, itemId, area, siteId).then((comments) => { | ||||
|             return !!comments.length; | ||||
|     getComments(contextLevel: string, instanceId: number, component: string, itemId: number, area: string = '', | ||||
|             siteId?: string): Promise<any> { | ||||
|         let comments = []; | ||||
| 
 | ||||
|         siteId = siteId || this.sitesProvider.getCurrentSiteId(); | ||||
| 
 | ||||
|         return this.getComment(contextLevel, instanceId, component, itemId, area, siteId).then((comment) => { | ||||
|             comments = comment ? [comment] : []; | ||||
| 
 | ||||
|             return this.getDeletedComments(contextLevel, instanceId, component, itemId, area, siteId); | ||||
|         }).then((deletedComments) => { | ||||
|             comments = comments.concat(deletedComments); | ||||
| 
 | ||||
|             return comments; | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Get all offline deleted comments. | ||||
|      * | ||||
|      * @param  {string} [siteId] Site ID. If not defined, current site. | ||||
|      * @return {Promise<any>}    Promise resolved with comments. | ||||
|      */ | ||||
|     getAllDeletedComments(siteId?: string): Promise<any> { | ||||
|         return this.sitesProvider.getSite(siteId).then((site) => { | ||||
|             return site.getDb().getRecords(CoreCommentsOfflineProvider.COMMENTS_DELETED_TABLE); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Get an offline comment. | ||||
|      * | ||||
|      * @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<any>}       Promise resolved with the comments. | ||||
|      */ | ||||
|     getDeletedComments(contextLevel: string, instanceId: number, component: string, itemId: number, area: string = '', | ||||
|             siteId?: string): Promise<any> { | ||||
|         return this.sitesProvider.getSite(siteId).then((site) => { | ||||
|             return site.getDb().getRecords(CoreCommentsOfflineProvider.COMMENTS_DELETED_TABLE, { | ||||
|                 contextlevel: contextLevel, | ||||
|                 instanceid: instanceId, | ||||
|                 component: component, | ||||
|                 itemid: itemId, | ||||
|                 area: area | ||||
|             }); | ||||
|         }).catch(() => { | ||||
|             return false; | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Remove an offline comment. | ||||
|      * | ||||
|      * @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<any>}       Promise resolved if deleted, rejected if failure. | ||||
|      */ | ||||
|     removeComment(contextLevel: string, instanceId: number, component: string, itemId: number, area: string = '', | ||||
|             siteId?: string): Promise<any> { | ||||
|         return this.sitesProvider.getSite(siteId).then((site) => { | ||||
|             return site.getDb().deleteRecords(CoreCommentsOfflineProvider.COMMENTS_TABLE, { | ||||
|                 contextlevel: contextLevel, | ||||
|                 instanceid: instanceId, | ||||
|                 component: component, | ||||
|                 itemid: itemId, | ||||
|                 area: area | ||||
|             }); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Remove an offline deleted comment. | ||||
|      * | ||||
|      * @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<any>}       Promise resolved if deleted, rejected if failure. | ||||
|      */ | ||||
|     removeDeletedComments(contextLevel: string, instanceId: number, component: string, itemId: number, area: string = '', | ||||
|             siteId?: string): Promise<any> { | ||||
|         return this.sitesProvider.getSite(siteId).then((site) => { | ||||
|             return site.getDb().deleteRecords(CoreCommentsOfflineProvider.COMMENTS_DELETED_TABLE, { | ||||
|                 contextlevel: contextLevel, | ||||
|                 instanceid: instanceId, | ||||
|                 component: component, | ||||
|                 itemid: itemId, | ||||
|                 area: area | ||||
|             }); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
| @ -175,7 +282,6 @@ export class CoreCommentsOfflineProvider { | ||||
|                 itemid: itemId, | ||||
|                 area: area, | ||||
|                 content: content, | ||||
|                 action: 'add', | ||||
|                 lastmodified: now | ||||
|             }; | ||||
| 
 | ||||
| @ -184,4 +290,49 @@ export class CoreCommentsOfflineProvider { | ||||
|             }); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Delete a comment offline to be sent later. | ||||
|      * | ||||
|      * @param  {number} commentId    Comment ID. | ||||
|      * @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<any>}        Promise resolved if stored, rejected if failure. | ||||
|      */ | ||||
|     deleteComment(commentId: number, contextLevel: string, instanceId: number, component: string, itemId: number, | ||||
|             area: string = '', siteId?: string): Promise<any> { | ||||
|         return this.sitesProvider.getSite(siteId).then((site) => { | ||||
|             const now = this.timeUtils.timestamp(); | ||||
|             const data = { | ||||
|                 contextlevel: contextLevel, | ||||
|                 instanceid: instanceId, | ||||
|                 component: component, | ||||
|                 itemid: itemId, | ||||
|                 area: area, | ||||
|                 commentid: commentId, | ||||
|                 deleted: now | ||||
|             }; | ||||
| 
 | ||||
|             return site.getDb().insertRecord(CoreCommentsOfflineProvider.COMMENTS_DELETED_TABLE, data).then(() => { | ||||
|                 return data; | ||||
|             }); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Undo delete a comment. | ||||
|      * | ||||
|      * @param  {number} commentId   Comment ID. | ||||
|      * @param  {string} [siteId]    Site ID. If not defined, current site. | ||||
|      * @return {Promise<any>}       Promise resolved if deleted, rejected if failure. | ||||
|      */ | ||||
|     undoDeleteComment(commentId: number, siteId?: string): Promise<any> { | ||||
|         return this.sitesProvider.getSite(siteId).then((site) => { | ||||
|             return site.getDb().deleteRecords(CoreCommentsOfflineProvider.COMMENTS_DELETED_TABLE, { commentid: commentId }); | ||||
|         }); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -19,7 +19,6 @@ import { CoreSyncBaseProvider } from '@classes/base-sync'; | ||||
| import { CoreAppProvider } from '@providers/app'; | ||||
| import { CoreCommentsOfflineProvider } from './offline'; | ||||
| import { CoreCommentsProvider } from './comments'; | ||||
| import { CoreCoursesProvider } from '@core/courses/providers/courses'; | ||||
| import { CoreEventsProvider } from '@providers/events'; | ||||
| import { CoreTextUtilsProvider } from '@providers/utils/text'; | ||||
| import { CoreTimeUtilsProvider } from '@providers/utils/time'; | ||||
| @ -39,7 +38,7 @@ export class CoreCommentsSyncProvider extends CoreSyncBaseProvider { | ||||
|             syncProvider: CoreSyncProvider, textUtils: CoreTextUtilsProvider, translate: TranslateService, | ||||
|             private commentsOffline: CoreCommentsOfflineProvider, private utils: CoreUtilsProvider, | ||||
|             private eventsProvider: CoreEventsProvider,  private commentsProvider: CoreCommentsProvider, | ||||
|             private coursesProvider: CoreCoursesProvider, timeUtils: CoreTimeUtilsProvider) { | ||||
|             timeUtils: CoreTimeUtilsProvider) { | ||||
| 
 | ||||
|         super('CoreCommentsSync', loggerProvider, sitesProvider, appProvider, syncProvider, textUtils, translate, timeUtils); | ||||
|     } | ||||
| @ -64,10 +63,19 @@ export class CoreCommentsSyncProvider extends CoreSyncBaseProvider { | ||||
|      */ | ||||
|     private syncAllCommentsFunc(siteId: string, force: boolean): Promise<any> { | ||||
|         return this.commentsOffline.getAllComments(siteId).then((comments) => { | ||||
| 
 | ||||
|             // Get Unique array.
 | ||||
|             comments.forEach((comment) => { | ||||
|                 comment.syncId = this.getSyncId(comment.contextlevel, comment.instanceid, comment.component, comment.itemid, | ||||
|                     comment.area); | ||||
|             }); | ||||
| 
 | ||||
|             comments = this.utils.uniqueArray(comments, 'syncId'); | ||||
| 
 | ||||
|             // Sync all courses.
 | ||||
|             const promises = comments.map((comment) => { | ||||
|                 const promise = force ? this.syncComment(comment.contextlevel, comment.instanceid, comment.component, | ||||
|                     comment.itemid, comment.area, siteId) : this.syncCommentIfNeeded(comment.contextlevel, comment.instanceid, | ||||
|                 const promise = force ? this.syncComments(comment.contextlevel, comment.instanceid, comment.component, | ||||
|                     comment.itemid, comment.area, siteId) : this.syncCommentsIfNeeded(comment.contextlevel, comment.instanceid, | ||||
|                     comment.component, comment.itemid, comment.area, siteId); | ||||
| 
 | ||||
|                 return promise.then((warnings) => { | ||||
| @ -90,7 +98,7 @@ export class CoreCommentsSyncProvider extends CoreSyncBaseProvider { | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Sync course notes only if a certain time has passed since the last time. | ||||
|      * Sync course comments only if a certain time has passed since the last time. | ||||
|      * | ||||
|      * @param  {string} contextLevel Contextlevel system, course, user... | ||||
|      * @param  {number} instanceId   The Instance id of item associated with the context level. | ||||
| @ -98,21 +106,21 @@ export class CoreCommentsSyncProvider extends CoreSyncBaseProvider { | ||||
|      * @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<any>}    Promise resolved when the notes are synced or if they don't need to be synced. | ||||
|      * @return {Promise<any>}    Promise resolved when the comments are synced or if they don't need to be synced. | ||||
|      */ | ||||
|     private syncCommentIfNeeded(contextLevel: string, instanceId: number, component: string, itemId: number, area: string = '', | ||||
|     private syncCommentsIfNeeded(contextLevel: string, instanceId: number, component: string, itemId: number, area: string = '', | ||||
|             siteId?: string): Promise<void> { | ||||
|         const syncId = this.getSyncId(contextLevel, instanceId, component, itemId, area); | ||||
| 
 | ||||
|         return this.isSyncNeeded(syncId, siteId).then((needed) => { | ||||
|             if (needed) { | ||||
|                 return this.syncComment(contextLevel, instanceId, component, itemId, area, siteId); | ||||
|                 return this.syncComments(contextLevel, instanceId, component, itemId, area, siteId); | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Synchronize notes of a course. | ||||
|      * Synchronize comments in a particular area. | ||||
|      * | ||||
|      * @param  {string} contextLevel Contextlevel system, course, user... | ||||
|      * @param  {number} instanceId   The Instance id of item associated with the context level. | ||||
| @ -122,14 +130,14 @@ export class CoreCommentsSyncProvider extends CoreSyncBaseProvider { | ||||
|      * @param  {string} [siteId] Site ID. If not defined, current site. | ||||
|      * @return {Promise<any>}    Promise resolved if sync is successful, rejected otherwise. | ||||
|      */ | ||||
|     syncComment(contextLevel: string, instanceId: number, component: string, itemId: number, area: string = '', | ||||
|     syncComments(contextLevel: string, instanceId: number, component: string, itemId: number, area: string = '', | ||||
|             siteId?: string): Promise<any> { | ||||
|         siteId = siteId || this.sitesProvider.getCurrentSiteId(); | ||||
| 
 | ||||
|         const syncId = this.getSyncId(contextLevel, instanceId, component, itemId, area); | ||||
| 
 | ||||
|         if (this.isSyncing(syncId, siteId)) { | ||||
|             // There's already a sync ongoing for notes, return the promise.
 | ||||
|             // There's already a sync ongoing for comments, return the promise.
 | ||||
|             return this.getOngoingSync(syncId, siteId); | ||||
|         } | ||||
| 
 | ||||
| @ -138,9 +146,9 @@ export class CoreCommentsSyncProvider extends CoreSyncBaseProvider { | ||||
|         const warnings = []; | ||||
| 
 | ||||
|         // Get offline comments to be sent.
 | ||||
|         const syncPromise = this.commentsOffline.getComment(contextLevel, instanceId, component, itemId, area, siteId) | ||||
|                 .then((comment) => { | ||||
|             if (!comment) { | ||||
|         const syncPromise = this.commentsOffline.getComments(contextLevel, instanceId, component, itemId, area, siteId) | ||||
|                 .then((comments) => { | ||||
|             if (!comments.length) { | ||||
|                 // Nothing to sync.
 | ||||
|                 return; | ||||
|             } else if (!this.appProvider.isOnline()) { | ||||
| @ -148,19 +156,31 @@ export class CoreCommentsSyncProvider extends CoreSyncBaseProvider { | ||||
|                 return Promise.reject(this.translate.instant('core.networkerrormsg')); | ||||
|             } | ||||
| 
 | ||||
|             const errors = []; | ||||
|             let commentsResponse = []; | ||||
|             let promise; | ||||
|             const errors = [], | ||||
|                 promises = [], | ||||
|                 deleteCommentIds = []; | ||||
| 
 | ||||
|             if (comment.action == 'add') { | ||||
|                 promise = this.commentsProvider.addCommentOnline(comment.content, contextLevel, instanceId, component, itemId, area, | ||||
|                     siteId); | ||||
|             comments.forEach((comment) => { | ||||
|                 if (comment.commentid) { | ||||
|                     deleteCommentIds.push(comment.commentid); | ||||
|                 } else { | ||||
|                     promises.push(this.commentsProvider.addCommentOnline(comment.content, contextLevel, instanceId, component, | ||||
|                         itemId, area, siteId).then((response) => { | ||||
|                             return this.commentsOffline.removeComment(contextLevel, instanceId, component, itemId, area, siteId); | ||||
|                     })); | ||||
|                 } | ||||
|             }); | ||||
| 
 | ||||
|             if (deleteCommentIds.length > 0) { | ||||
|                 promises.push(this.commentsProvider.deleteCommentsOnline(deleteCommentIds, contextLevel, instanceId, component, | ||||
|                     itemId, area, siteId).then((response) => { | ||||
|                         return this.commentsOffline.removeDeletedComments(contextLevel, instanceId, component, itemId, area, | ||||
|                             siteId); | ||||
|                     })); | ||||
|             } | ||||
| 
 | ||||
|             // Send the comments.
 | ||||
|             return promise.then((response) => { | ||||
|                 commentsResponse = response; | ||||
| 
 | ||||
|             return Promise.all(promises).then(() => { | ||||
|                 // Fetch the comments from server to be sure they're up to date.
 | ||||
|                 return this.commentsProvider.invalidateCommentsData(contextLevel, instanceId, component, itemId, area, siteId) | ||||
|                         .then(() => { | ||||
| @ -171,27 +191,15 @@ export class CoreCommentsSyncProvider extends CoreSyncBaseProvider { | ||||
|             }).catch((error) => { | ||||
|                 if (this.utils.isWebServiceError(error)) { | ||||
|                     // It's a WebService error, this means the user cannot send comments.
 | ||||
|                     errors.push(error); | ||||
|                     errors.push(error.message); | ||||
|                 } else { | ||||
|                     // Not a WebService error, reject the synchronization to try again.
 | ||||
|                     return Promise.reject(error); | ||||
|                 } | ||||
|             }).then(() => { | ||||
|                 // Notes were sent, delete them from local DB.
 | ||||
|                 const promises = commentsResponse.map((comment) => { | ||||
|                     return this.commentsOffline.removeComment(contextLevel, instanceId, component, itemId, area, siteId); | ||||
|                 }); | ||||
| 
 | ||||
|                 return Promise.all(promises); | ||||
|             }).then(() => { | ||||
|                 if (errors && errors.length) { | ||||
|                     errors.forEach((error) => { | ||||
|                         warnings.push(this.translate.instant('addon.notes.warningnotenotsent', { | ||||
|                             contextLevel: contextLevel, | ||||
|                             instanceId: instanceId, | ||||
|                             componentName: component, | ||||
|                             itemId: itemId, | ||||
|                             area: area, | ||||
|                         warnings.push(this.translate.instant('core.comments.warningcommentsnotsent', { | ||||
|                             error: error | ||||
|                         })); | ||||
|                     }); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user