MOBILE-1332 notes: Delete notes in offline mode
This commit is contained in:
		
							parent
							
								
									58b2e33156
								
							
						
					
					
						commit
						f597abd33f
					
				| @ -38,9 +38,18 @@ | |||||||
|                 <ion-item text-wrap> |                 <ion-item text-wrap> | ||||||
|                     <ion-avatar core-user-avatar [user]="note" [courseId]="courseId" item-start *ngIf="!userId"></ion-avatar> |                     <ion-avatar core-user-avatar [user]="note" [courseId]="courseId" item-start *ngIf="!userId"></ion-avatar> | ||||||
|                     <h2 *ngIf="!userId">{{note.userfullname}}</h2> |                     <h2 *ngIf="!userId">{{note.userfullname}}</h2> | ||||||
|                     <p *ngIf="!note.offline" item-end>{{note.lastmodified | coreDateDayOrTime}}</p> |                     <p *ngIf="!note.deleted && !note.offline" item-end> | ||||||
|                     <p *ngIf="note.offline" item-end><ion-icon name="time"></ion-icon> {{ 'core.notsent' | translate }}</p> |                         <span text-wrap>{{note.lastmodified | coreDateDayOrTime}}</span> | ||||||
|                     <button *ngIf="showDelete && (type != 'personal' || note.usermodified == currentUserId)" item-end ion-button icon-only clear [@coreSlideInOut]="'fromRight'" color="danger" (click)="deleteNote($event, note)" [attr.aria-label]="'core.delete' | translate"> |                     </p> | ||||||
|  |                     <p *ngIf="note.offline" item-end> | ||||||
|  |                         <ion-icon name="time"></ion-icon> <span text-wrap>{{ 'core.notsent' | translate }}</span></p> | ||||||
|  |                     <p *ngIf="note.deleted" item-end> | ||||||
|  |                         <ion-icon name="trash"></ion-icon> <span text-wrap>{{ 'core.deletedoffline' | translate }}</span> | ||||||
|  |                     </p> | ||||||
|  |                     <button *ngIf="note.deleted" item-end ion-button icon-only clear color="danger" (click)="undoDeleteNote($event, note)" [attr.aria-label]="'core.restore' | translate"> | ||||||
|  |                         <ion-icon name="undo"></ion-icon> | ||||||
|  |                     </button> | ||||||
|  |                     <button *ngIf="showDelete && !note.deleted && (type != 'personal' || note.usermodified == currentUserId)" item-end ion-button icon-only clear [@coreSlideInOut]="'fromRight'" color="danger" (click)="deleteNote($event, note)" [attr.aria-label]="'core.delete' | translate"> | ||||||
|                         <ion-icon name="trash"></ion-icon> |                         <ion-icon name="trash"></ion-icon> | ||||||
|                     </button> |                     </button> | ||||||
|                 </ion-item> |                 </ion-item> | ||||||
|  | |||||||
| @ -22,6 +22,7 @@ import { CoreTextUtilsProvider } from '@providers/utils/text'; | |||||||
| import { CoreUserProvider } from '@core/user/providers/user'; | import { CoreUserProvider } from '@core/user/providers/user'; | ||||||
| import { coreSlideInOut } from '@classes/animations'; | import { coreSlideInOut } from '@classes/animations'; | ||||||
| import { AddonNotesProvider } from '../../providers/notes'; | import { AddonNotesProvider } from '../../providers/notes'; | ||||||
|  | import { AddonNotesOfflineProvider } from '../../providers/notes-offline'; | ||||||
| import { AddonNotesSyncProvider } from '../../providers/notes-sync'; | import { AddonNotesSyncProvider } from '../../providers/notes-sync'; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
| @ -54,7 +55,8 @@ export class AddonNotesListComponent implements OnInit, OnDestroy { | |||||||
|     constructor(private domUtils: CoreDomUtilsProvider, private textUtils: CoreTextUtilsProvider, |     constructor(private domUtils: CoreDomUtilsProvider, private textUtils: CoreTextUtilsProvider, | ||||||
|             sitesProvider: CoreSitesProvider, eventsProvider: CoreEventsProvider, private modalCtrl: ModalController, |             sitesProvider: CoreSitesProvider, eventsProvider: CoreEventsProvider, private modalCtrl: ModalController, | ||||||
|             private notesProvider: AddonNotesProvider, private notesSync: AddonNotesSyncProvider, |             private notesProvider: AddonNotesProvider, private notesSync: AddonNotesSyncProvider, | ||||||
|             private userProvider: CoreUserProvider, private translate: TranslateService) { |             private userProvider: CoreUserProvider, private translate: TranslateService, | ||||||
|  |             private notesOffline: AddonNotesOfflineProvider) { | ||||||
|         // Refresh data if notes are synchronized automatically.
 |         // Refresh data if notes are synchronized automatically.
 | ||||||
|         this.syncObserver = eventsProvider.on(AddonNotesSyncProvider.AUTO_SYNCED, (data) => { |         this.syncObserver = eventsProvider.on(AddonNotesSyncProvider.AUTO_SYNCED, (data) => { | ||||||
|             if (data.courseId == this.courseId) { |             if (data.courseId == this.courseId) { | ||||||
| @ -101,7 +103,9 @@ export class AddonNotesListComponent implements OnInit, OnDestroy { | |||||||
|             return this.notesProvider.getNotes(this.courseId, this.userId).then((notes) => { |             return this.notesProvider.getNotes(this.courseId, this.userId).then((notes) => { | ||||||
|                 notes = notes[this.type + 'notes'] || []; |                 notes = notes[this.type + 'notes'] || []; | ||||||
| 
 | 
 | ||||||
|                 this.hasOffline = notes.some((note) => note.offline); |                 return this.notesProvider.setOfflineDeletedNotes(notes, this.courseId).then((notes) => { | ||||||
|  | 
 | ||||||
|  |                     this.hasOffline = notes.some((note) => note.offline || note.deleted); | ||||||
| 
 | 
 | ||||||
|                     if (this.userId) { |                     if (this.userId) { | ||||||
|                         this.notes = notes; |                         this.notes = notes; | ||||||
| @ -116,6 +120,7 @@ export class AddonNotesListComponent implements OnInit, OnDestroy { | |||||||
|                         }); |                         }); | ||||||
|                     } |                     } | ||||||
|                 }); |                 }); | ||||||
|  |             }); | ||||||
|         }).catch((message) => { |         }).catch((message) => { | ||||||
|             this.domUtils.showErrorModal(message); |             this.domUtils.showErrorModal(message); | ||||||
|         }).finally(() => { |         }).finally(() => { | ||||||
| @ -201,7 +206,7 @@ export class AddonNotesListComponent implements OnInit, OnDestroy { | |||||||
|         e.stopPropagation(); |         e.stopPropagation(); | ||||||
| 
 | 
 | ||||||
|         this.domUtils.showConfirm(this.translate.instant('addon.notes.deleteconfirm')).then(() => { |         this.domUtils.showConfirm(this.translate.instant('addon.notes.deleteconfirm')).then(() => { | ||||||
|             this.notesProvider.deleteNote(note).then(() => { |             this.notesProvider.deleteNote(note, this.courseId).then(() => { | ||||||
|                 this.showDelete = false; |                 this.showDelete = false; | ||||||
| 
 | 
 | ||||||
|                 this.refreshNotes(true); |                 this.refreshNotes(true); | ||||||
| @ -215,6 +220,21 @@ export class AddonNotesListComponent implements OnInit, OnDestroy { | |||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     /** | ||||||
|  |      * Restore a note. | ||||||
|  |      * | ||||||
|  |      * @param {Event} e Click event. | ||||||
|  |      * @param {any} note Note to delete. | ||||||
|  |      */ | ||||||
|  |     undoDeleteNote(e: Event, note: any): void { | ||||||
|  |         e.preventDefault(); | ||||||
|  |         e.stopPropagation(); | ||||||
|  | 
 | ||||||
|  |         this.notesOffline.undoDeleteNote(note.id).then(() => { | ||||||
|  |             this.refreshNotes(true); | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     /** |     /** | ||||||
|      * Toggle delete. |      * Toggle delete. | ||||||
|      */ |      */ | ||||||
|  | |||||||
| @ -26,9 +26,10 @@ export class AddonNotesOfflineProvider { | |||||||
| 
 | 
 | ||||||
|     // Variables for database.
 |     // Variables for database.
 | ||||||
|     static NOTES_TABLE = 'addon_notes_offline_notes'; |     static NOTES_TABLE = 'addon_notes_offline_notes'; | ||||||
|  |     static NOTES_DELETED_TABLE = 'addon_notes_deleted_offline_notes'; | ||||||
|     protected siteSchema: CoreSiteSchema = { |     protected siteSchema: CoreSiteSchema = { | ||||||
|         name: 'AddonNotesOfflineProvider', |         name: 'AddonNotesOfflineProvider', | ||||||
|         version: 1, |         version: 2, | ||||||
|         tables: [ |         tables: [ | ||||||
|             { |             { | ||||||
|                 name: AddonNotesOfflineProvider.NOTES_TABLE, |                 name: AddonNotesOfflineProvider.NOTES_TABLE, | ||||||
| @ -63,6 +64,24 @@ export class AddonNotesOfflineProvider { | |||||||
|                     } |                     } | ||||||
|                 ], |                 ], | ||||||
|                 primaryKeys: ['userid', 'content', 'created'] |                 primaryKeys: ['userid', 'content', 'created'] | ||||||
|  |             }, | ||||||
|  |             { | ||||||
|  |                 name: AddonNotesOfflineProvider.NOTES_DELETED_TABLE, | ||||||
|  |                 columns: [ | ||||||
|  |                     { | ||||||
|  |                         name: 'noteid', | ||||||
|  |                         type: 'INTEGER', | ||||||
|  |                         primaryKey: true | ||||||
|  |                     }, | ||||||
|  |                     { | ||||||
|  |                         name: 'deleted', | ||||||
|  |                         type: 'INTEGER' | ||||||
|  |                     }, | ||||||
|  |                     { | ||||||
|  |                         name: 'courseid', | ||||||
|  |                         type: 'INTEGER' | ||||||
|  |                     } | ||||||
|  |                 ] | ||||||
|             } |             } | ||||||
|         ] |         ] | ||||||
|     }; |     }; | ||||||
| @ -73,7 +92,7 @@ export class AddonNotesOfflineProvider { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Delete a note. |      * Delete an offline note. | ||||||
|      * |      * | ||||||
|      * @param  {number} userId      User ID the note is about. |      * @param  {number} userId      User ID the note is about. | ||||||
|      * @param  {string} content     The note content. |      * @param  {string} content     The note content. | ||||||
| @ -81,7 +100,7 @@ export class AddonNotesOfflineProvider { | |||||||
|      * @param  {string} [siteId]    Site ID. If not defined, current site. |      * @param  {string} [siteId]    Site ID. If not defined, current site. | ||||||
|      * @return {Promise<any>}       Promise resolved if deleted, rejected if failure. |      * @return {Promise<any>}       Promise resolved if deleted, rejected if failure. | ||||||
|      */ |      */ | ||||||
|     deleteNote(userId: number, content: string, timecreated: number, siteId?: string): Promise<any> { |     deleteOfflineNote(userId: number, content: string, timecreated: number, siteId?: string): Promise<any> { | ||||||
|         return this.sitesProvider.getSite(siteId).then((site) => { |         return this.sitesProvider.getSite(siteId).then((site) => { | ||||||
|             return site.getDb().deleteRecords(AddonNotesOfflineProvider.NOTES_TABLE, { |             return site.getDb().deleteRecords(AddonNotesOfflineProvider.NOTES_TABLE, { | ||||||
|                 userid: userId, |                 userid: userId, | ||||||
| @ -91,6 +110,31 @@ export class AddonNotesOfflineProvider { | |||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     /** | ||||||
|  |      * Get all offline deleted notes. | ||||||
|  |      * | ||||||
|  |      * @param  {string} [siteId] Site ID. If not defined, current site. | ||||||
|  |      * @return {Promise<any>}    Promise resolved with notes. | ||||||
|  |      */ | ||||||
|  |     getAllDeletedNotes(siteId?: string): Promise<any> { | ||||||
|  |         return this.sitesProvider.getSite(siteId).then((site) => { | ||||||
|  |             return site.getDb().getRecords(AddonNotesOfflineProvider.NOTES_DELETED_TABLE); | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Get course offline deleted notes. | ||||||
|  |      * | ||||||
|  |      * @param  {number} courseId Course ID. | ||||||
|  |      * @param  {string} [siteId] Site ID. If not defined, current site. | ||||||
|  |      * @return {Promise<any>}    Promise resolved with notes. | ||||||
|  |      */ | ||||||
|  |     getCourseDeletedNotes(courseId: number, siteId?: string): Promise<any> { | ||||||
|  |         return this.sitesProvider.getSite(siteId).then((site) => { | ||||||
|  |             return site.getDb().getRecords(AddonNotesOfflineProvider.NOTES_DELETED_TABLE, {courseid: courseId}); | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     /** |     /** | ||||||
|      * Get all offline notes. |      * Get all offline notes. | ||||||
|      * |      * | ||||||
| @ -246,4 +290,40 @@ export class AddonNotesOfflineProvider { | |||||||
|             }); |             }); | ||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Delete a note offline to be sent later. | ||||||
|  |      * | ||||||
|  |      * @param  {number} noteId   Note ID. | ||||||
|  |      * @param  {number} courseId Course ID. | ||||||
|  |      * @param  {string} [siteId] Site ID. If not defined, current site. | ||||||
|  |      * @return {Promise<any>}    Promise resolved if stored, rejected if failure. | ||||||
|  |      */ | ||||||
|  |     deleteNote(noteId: number, courseId: number, siteId?: string): Promise<any> { | ||||||
|  |         return this.sitesProvider.getSite(siteId).then((site) => { | ||||||
|  |             const now = this.timeUtils.timestamp(); | ||||||
|  |             const data = { | ||||||
|  |                 noteid: noteId, | ||||||
|  |                 courseid: courseId, | ||||||
|  |                 deleted: now | ||||||
|  |             }; | ||||||
|  | 
 | ||||||
|  |             return site.getDb().insertRecord(AddonNotesOfflineProvider.NOTES_DELETED_TABLE, data).then(() => { | ||||||
|  |                 return data; | ||||||
|  |             }); | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Undo delete a note. | ||||||
|  |      * | ||||||
|  |      * @param  {number} noteId   Note ID. | ||||||
|  |      * @param  {string} [siteId] Site ID. If not defined, current site. | ||||||
|  |      * @return {Promise<any>}    Promise resolved if deleted, rejected if failure. | ||||||
|  |      */ | ||||||
|  |     undoDeleteNote(noteId: number, siteId?: string): Promise<any> { | ||||||
|  |         return this.sitesProvider.getSite(siteId).then((site) => { | ||||||
|  |             return site.getDb().deleteRecords(AddonNotesOfflineProvider.NOTES_DELETED_TABLE, { noteid: noteId }); | ||||||
|  |         }); | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -63,18 +63,24 @@ export class AddonNotesSyncProvider extends CoreSyncBaseProvider { | |||||||
|      * @return {Promise<any>}  Promise resolved if sync is successful, rejected if sync fails. |      * @return {Promise<any>}  Promise resolved if sync is successful, rejected if sync fails. | ||||||
|      */ |      */ | ||||||
|     private syncAllNotesFunc(siteId: string, force: boolean): Promise<any> { |     private syncAllNotesFunc(siteId: string, force: boolean): Promise<any> { | ||||||
|         return this.notesOffline.getAllNotes(siteId).then((notes) => { |         const proms = []; | ||||||
|             // Get all the courses to be synced.
 |  | ||||||
|             const courseIds = []; |  | ||||||
|             notes.forEach((note) => { |  | ||||||
|                 if (courseIds.indexOf(note.courseid) == -1) { |  | ||||||
|                     courseIds.push(note.courseid); |  | ||||||
|                 } |  | ||||||
|             }); |  | ||||||
| 
 | 
 | ||||||
|  |         proms.push(this.notesOffline.getAllNotes(siteId)); | ||||||
|  |         proms.push(this.notesOffline.getAllDeletedNotes(siteId)); | ||||||
|  | 
 | ||||||
|  |         return Promise.all(proms).then((notesArray) => { | ||||||
|  |             // Get all the courses to be synced.
 | ||||||
|  |             const courseIds = {}; | ||||||
|  |             notesArray.forEach((notes) => { | ||||||
|  |                 notes.forEach((note) => { | ||||||
|  |                     courseIds[note.courseid] = note.courseid; | ||||||
|  |                 }); | ||||||
|  |             }); | ||||||
|             // Sync all courses.
 |             // Sync all courses.
 | ||||||
|             const promises = courseIds.map((courseId) => { |             const promises = Object.keys(courseIds).map((courseId) => { | ||||||
|                 const promise = force ? this.syncNotes(courseId, siteId) : this.syncNotesIfNeeded(courseId, siteId); |                 const cId = parseInt(courseIds[courseId], 10); | ||||||
|  | 
 | ||||||
|  |                 const promise = force ? this.syncNotes(cId, siteId) : this.syncNotesIfNeeded(cId, siteId); | ||||||
| 
 | 
 | ||||||
|                 return promise.then((warnings) => { |                 return promise.then((warnings) => { | ||||||
|                     if (typeof warnings != 'undefined') { |                     if (typeof warnings != 'undefined') { | ||||||
| @ -124,9 +130,12 @@ export class AddonNotesSyncProvider extends CoreSyncBaseProvider { | |||||||
|         this.logger.debug('Try to sync notes for course ' + courseId); |         this.logger.debug('Try to sync notes for course ' + courseId); | ||||||
| 
 | 
 | ||||||
|         const warnings = []; |         const warnings = []; | ||||||
|  |         const errors = []; | ||||||
|  | 
 | ||||||
|  |         const proms = []; | ||||||
| 
 | 
 | ||||||
|         // Get offline notes to be sent.
 |         // Get offline notes to be sent.
 | ||||||
|         const syncPromise = this.notesOffline.getNotesForCourse(courseId, siteId).then((notes) => { |         proms.push(this.notesOffline.getNotesForCourse(courseId, siteId).then((notes) => { | ||||||
|             if (!notes.length) { |             if (!notes.length) { | ||||||
|                 // Nothing to sync.
 |                 // Nothing to sync.
 | ||||||
|                 return; |                 return; | ||||||
| @ -157,12 +166,6 @@ export class AddonNotesSyncProvider extends CoreSyncBaseProvider { | |||||||
|                     } |                     } | ||||||
|                 }); |                 }); | ||||||
| 
 | 
 | ||||||
|                 // Fetch the notes from server to be sure they're up to date.
 |  | ||||||
|                 return this.notesProvider.invalidateNotes(courseId, undefined, siteId).then(() => { |  | ||||||
|                     return this.notesProvider.getNotes(courseId, undefined, false, true, siteId); |  | ||||||
|                 }).catch(() => { |  | ||||||
|                     // Ignore errors.
 |  | ||||||
|                 }); |  | ||||||
|             }).catch((error) => { |             }).catch((error) => { | ||||||
|                 if (this.utils.isWebServiceError(error)) { |                 if (this.utils.isWebServiceError(error)) { | ||||||
|                     // It's a WebService error, this means the user cannot send notes.
 |                     // It's a WebService error, this means the user cannot send notes.
 | ||||||
| @ -174,10 +177,54 @@ export class AddonNotesSyncProvider extends CoreSyncBaseProvider { | |||||||
|             }).then(() => { |             }).then(() => { | ||||||
|                 // Notes were sent, delete them from local DB.
 |                 // Notes were sent, delete them from local DB.
 | ||||||
|                 const promises = notes.map((note) => { |                 const promises = notes.map((note) => { | ||||||
|                     return this.notesOffline.deleteNote(note.userid, note.content, note.created, siteId); |                     return this.notesOffline.deleteOfflineNote(note.userid, note.content, note.created, siteId); | ||||||
|                 }); |                 }); | ||||||
| 
 | 
 | ||||||
|                 return Promise.all(promises); |                 return Promise.all(promises); | ||||||
|  |             }); | ||||||
|  |         })); | ||||||
|  | 
 | ||||||
|  |         // Get offline notes to be sent.
 | ||||||
|  |         proms.push(this.notesOffline.getCourseDeletedNotes(courseId, siteId).then((notes) => { | ||||||
|  |             if (!notes.length) { | ||||||
|  |                 // Nothing to sync.
 | ||||||
|  |                 return; | ||||||
|  |             } else if (!this.appProvider.isOnline()) { | ||||||
|  |                 // Cannot sync in offline.
 | ||||||
|  |                 return Promise.reject(this.translate.instant('core.networkerrormsg')); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             // Format the notes to be sent.
 | ||||||
|  |             const notesToDelete = notes.map((note) => { | ||||||
|  |                 return note.noteid; | ||||||
|  |             }); | ||||||
|  | 
 | ||||||
|  |             // Delete the notes.
 | ||||||
|  |             return this.notesProvider.deleteNotesOnline(notesToDelete, courseId, siteId).catch((error) => { | ||||||
|  |                 if (this.utils.isWebServiceError(error)) { | ||||||
|  |                     // It's a WebService error, this means the user cannot send notes.
 | ||||||
|  |                     errors.push(error); | ||||||
|  |                 } 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 = notes.map((noteId) => { | ||||||
|  |                     return this.notesOffline.undoDeleteNote(noteId, siteId); | ||||||
|  |                 }); | ||||||
|  | 
 | ||||||
|  |                 return Promise.all(promises); | ||||||
|  |             }); | ||||||
|  |         })); | ||||||
|  | 
 | ||||||
|  |         const syncPromise = Promise.all(proms).then(() => { | ||||||
|  |             // Fetch the notes from server to be sure they're up to date.
 | ||||||
|  |             return this.notesProvider.invalidateNotes(courseId, undefined, siteId).then(() => { | ||||||
|  |                 return this.notesProvider.getNotes(courseId, undefined, false, true, siteId); | ||||||
|  |             }).catch(() => { | ||||||
|  |                 // Ignore errors.
 | ||||||
|  |             }); | ||||||
|         }).then(() => { |         }).then(() => { | ||||||
|             if (errors && errors.length) { |             if (errors && errors.length) { | ||||||
|                 // At least an error occurred, get course name and add errors to warnings array.
 |                 // At least an error occurred, get course name and add errors to warnings array.
 | ||||||
| @ -193,7 +240,6 @@ export class AddonNotesSyncProvider extends CoreSyncBaseProvider { | |||||||
|                     }); |                     }); | ||||||
|                 }); |                 }); | ||||||
|             } |             } | ||||||
|             }); |  | ||||||
|         }).then(() => { |         }).then(() => { | ||||||
|             // All done, return the warnings.
 |             // All done, return the warnings.
 | ||||||
|             return warnings; |             return warnings; | ||||||
|  | |||||||
| @ -137,20 +137,65 @@ export class AddonNotesProvider { | |||||||
|      * Delete a note. |      * Delete a note. | ||||||
|      * |      * | ||||||
|      * @param  {any} note            Note object to delete. |      * @param  {any} note            Note object to delete. | ||||||
|  |      * @param  {number} courseId     Course ID where the note belongs. | ||||||
|      * @param  {string} [siteId]     Site ID. If not defined, current site. |      * @param  {string} [siteId]     Site ID. If not defined, current site. | ||||||
|      * @return {Promise<void>}       Promise resolved when done. |      * @return {Promise<void>}       Promise resolved when deleted, rejected otherwise. Promise resolved doesn't mean that notes | ||||||
|  |      *                               have been deleted, the resolve param can contain errors for notes not deleted. | ||||||
|      */ |      */ | ||||||
|     deleteNote(note: any, siteId?: string): Promise<void> { |     deleteNote(note: any, courseId: number, siteId?: string): Promise<void> { | ||||||
|         return this.sitesProvider.getSite(siteId).then((site) => { |         siteId = siteId || this.sitesProvider.getCurrentSiteId(); | ||||||
|             if (typeof note.offline != 'undefined' && note.offline) { | 
 | ||||||
|                 return this.notesOffline.deleteNote(note.userid, note.content, note.created, site.id); |         if (note.offline) { | ||||||
|  |             return this.notesOffline.deleteOfflineNote(note.userid, note.content, note.created, siteId); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|             const data = { |         // Convenience function to store the action to be synchronized later.
 | ||||||
|                 notes: [note.id] |         const storeOffline = (): Promise<any> => { | ||||||
|  |             return this.notesOffline.deleteNote(note.id, courseId, siteId).then(() => { | ||||||
|  |                 return false; | ||||||
|  |             }); | ||||||
|         }; |         }; | ||||||
| 
 | 
 | ||||||
|             return site.write('core_notes_delete_notes', data); |         if (!this.appProvider.isOnline()) { | ||||||
|  |             // App is offline, store the note.
 | ||||||
|  |             return storeOffline(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // Send note to server.
 | ||||||
|  |         return this.deleteNotesOnline([note.id], courseId, siteId).then(() => { | ||||||
|  |             return true; | ||||||
|  |         }).catch((error) => { | ||||||
|  |             if (this.utils.isWebServiceError(error)) { | ||||||
|  |                 // It's a WebService error, the user cannot send the note so don't store it.
 | ||||||
|  |                 return Promise.reject(error); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             // Error sending note, store it to retry later.
 | ||||||
|  |             return storeOffline(); | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Delete a note. It will fail if offline or cannot connect. | ||||||
|  |      * | ||||||
|  |      * @param  {number[]} noteIds    Note IDs to delete. | ||||||
|  |      * @param  {number} courseId     Course ID where the note belongs. | ||||||
|  |      * @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 notes | ||||||
|  |      *                               have been deleted, the resolve param can contain errors for notes not deleted. | ||||||
|  |      */ | ||||||
|  |     deleteNotesOnline(noteIds: number[], courseId: number, siteId?: string): Promise<void> { | ||||||
|  |         return this.sitesProvider.getSite(siteId).then((site) => { | ||||||
|  |             const data = { | ||||||
|  |                 notes: noteIds | ||||||
|  |             }; | ||||||
|  | 
 | ||||||
|  |             return site.write('core_notes_delete_notes', data).then((response) => { | ||||||
|  |                 // A note was deleted, invalidate the course notes.
 | ||||||
|  |                 return this.invalidateNotes(courseId, undefined, siteId).catch(() => { | ||||||
|  |                     // Ignore errors.
 | ||||||
|  |                 }); | ||||||
|  |             }); | ||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -288,6 +333,24 @@ export class AddonNotesProvider { | |||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     /** | ||||||
|  |      * Get offline deleted notes and set the state. | ||||||
|  |      * | ||||||
|  |      * @param  {any[]}   notes     Array of notes. | ||||||
|  |      * @param  {number} courseId ID of the course the notes belong to. | ||||||
|  |      * @param  {string}  [siteId]  Site ID. If not defined, current site. | ||||||
|  |      * @return {Promise<any>}       [description] | ||||||
|  |      */ | ||||||
|  |     setOfflineDeletedNotes(notes: any[], courseId: number, siteId?: string): Promise<any> { | ||||||
|  |         return this.notesOffline.getCourseDeletedNotes(courseId, siteId).then((deletedNotes) => { | ||||||
|  |             notes.forEach((note) => { | ||||||
|  |                 note.deleted = deletedNotes.some((n) => n.noteid == note.id); | ||||||
|  |             }); | ||||||
|  | 
 | ||||||
|  |             return notes; | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     /** |     /** | ||||||
|      * Get user data for notes since they only have userid. |      * Get user data for notes since they only have userid. | ||||||
|      * |      * | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user