From 5533c39288706def9fd5f9d0881fde9eb5eb8a0f Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Wed, 28 Aug 2019 10:38:44 +0200 Subject: [PATCH] MOBILE-3068 database: Fix comments not updated on PTR --- src/addon/mod/data/components/index/index.ts | 9 ++-- src/addon/mod/data/pages/entry/entry.ts | 13 +++-- src/addon/mod/data/providers/helper.ts | 9 ++-- .../comments/components/comments/comments.ts | 52 ++++++++++++++++++- src/core/comments/providers/comments.ts | 2 + 5 files changed, 73 insertions(+), 12 deletions(-) diff --git a/src/addon/mod/data/components/index/index.ts b/src/addon/mod/data/components/index/index.ts index ae91044ae..bc3463842 100644 --- a/src/addon/mod/data/components/index/index.ts +++ b/src/addon/mod/data/components/index/index.ts @@ -85,7 +85,6 @@ export class AddonModDataIndexComponent extends CoreCourseModuleMainActivityComp private prefetchHandler: AddonModDataPrefetchHandler, private timeUtils: CoreTimeUtilsProvider, private groupsProvider: CoreGroupsProvider, - private commentsProvider: CoreCommentsProvider, private modalCtrl: ModalController, private utils: CoreUtilsProvider, protected navCtrl: NavController) { @@ -152,8 +151,12 @@ export class AddonModDataIndexComponent extends CoreCourseModuleMainActivityComp promises.push(this.dataProvider.invalidateDatabaseAccessInformationData(this.data.id)); promises.push(this.groupsProvider.invalidateActivityGroupInfo(this.data.coursemodule)); promises.push(this.dataProvider.invalidateEntriesData(this.data.id)); + if (this.hasComments) { - promises.push(this.commentsProvider.invalidateCommentsByInstance('module', this.data.coursemodule)); + this.eventsProvider.trigger(CoreCommentsProvider.REFRESH_COMMENTS_EVENT, { + contextLevel: 'module', + instanceId: this.data.coursemodule + }, this.sitesProvider.getCurrentSiteId()); } } @@ -192,6 +195,7 @@ export class AddonModDataIndexComponent extends CoreCourseModuleMainActivityComp return this.dataProvider.getDatabase(this.courseId, this.module.id).then((data) => { this.data = data; + this.hasComments = data.comments; this.description = data.intro || data.description; this.dataRetrieved.emit(data); @@ -258,7 +262,6 @@ export class AddonModDataIndexComponent extends CoreCourseModuleMainActivityComp * @return {Promise} Resolved then done. */ protected fetchEntriesData(): Promise { - this.hasComments = false; return this.dataProvider.getDatabaseAccessInformation(this.data.id, this.selectedGroup).then((accessData) => { // Update values for current group. diff --git a/src/addon/mod/data/pages/entry/entry.ts b/src/addon/mod/data/pages/entry/entry.ts index e486cdf5f..95f96d8fc 100644 --- a/src/addon/mod/data/pages/entry/entry.ts +++ b/src/addon/mod/data/pages/entry/entry.ts @@ -27,6 +27,7 @@ import { AddonModDataSyncProvider } from '../../providers/sync'; import { AddonModDataFieldsDelegate } from '../../providers/fields-delegate'; import { AddonModDataComponentsModule } from '../../components/components.module'; import { CoreCommentsProvider } from '@core/comments/providers/comments'; +import { CoreCommentsCommentsComponent } from '@core/comments/components/comments/comments'; /** * Page that displays the view entry page. @@ -38,6 +39,7 @@ import { CoreCommentsProvider } from '@core/comments/providers/comments'; }) export class AddonModDataEntryPage implements OnDestroy { @ViewChild(Content) content: Content; + @ViewChild(CoreCommentsCommentsComponent) comments: CoreCommentsCommentsComponent; protected module: any; protected entryId: number; @@ -211,13 +213,16 @@ export class AddonModDataEntryPage implements OnDestroy { promises.push(this.dataProvider.invalidateDatabaseData(this.courseId)); if (this.data) { - if (this.data.comments && this.entry && this.entry.id > 0 && this.commentsEnabled) { - promises.push(this.commentsProvider.invalidateCommentsData('module', this.data.coursemodule, 'mod_data', - this.entry.id, 'database_entry')); - } promises.push(this.dataProvider.invalidateEntryData(this.data.id, this.entryId)); promises.push(this.groupsProvider.invalidateActivityGroupInfo(this.data.coursemodule)); promises.push(this.dataProvider.invalidateEntriesData(this.data.id)); + + if (this.data.comments && this.entry && this.entry.id > 0 && this.commentsEnabled && this.comments) { + // Refresh comments. Don't add it to promises because we don't want the comments fetch to block the entry fetch. + this.comments.doRefresh().catch(() => { + // Ignore errors. + }); + } } return Promise.all(promises).finally(() => { diff --git a/src/addon/mod/data/providers/helper.ts b/src/addon/mod/data/providers/helper.ts index a9e52775b..2938c6c72 100644 --- a/src/addon/mod/data/providers/helper.ts +++ b/src/addon/mod/data/providers/helper.ts @@ -158,11 +158,12 @@ export class AddonModDataHelperProvider { * @param {any} entry Entry. * @param {number} offset Entry offset. * @param {string} mode Mode list or show. - * @param {AddonModDataOfflineAction[]} actions Actions that can be performed to the record. + * @param {{[name: string]: boolean}} actions Actions that can be performed to the record. * @return {string} Generated HTML. */ displayShowFields(template: string, fields: any[], entry: any, offset: number, mode: string, - actions: AddonModDataOfflineAction[]): string { + actions: {[name: string]: boolean}): string { + if (!template) { return ''; } @@ -357,9 +358,9 @@ export class AddonModDataHelperProvider { * @param {any} database Database activity. * @param {any} accessInfo Access info to the activity. * @param {any} record Entry or record where the actions will be performed. - * @return {any} Keyed with the action names and boolean to evalute if it can or cannot be done. + * @return {{[name: string]: boolean}} Keyed with the action names and boolean to evalute if it can or cannot be done. */ - getActions(database: any, accessInfo: any, record: any): any { + getActions(database: any, accessInfo: any, record: any): {[name: string]: boolean} { return { more: true, moreurl: true, diff --git a/src/core/comments/components/comments/comments.ts b/src/core/comments/components/comments/comments.ts index 6f7a22444..6e32bc710 100644 --- a/src/core/comments/components/comments/comments.ts +++ b/src/core/comments/components/comments/comments.ts @@ -41,6 +41,7 @@ export class CoreCommentsCommentsComponent implements OnChanges, OnDestroy { disabled = false; protected updateSiteObserver; + protected refreshCommentsObserver; constructor(private navCtrl: NavController, private commentsProvider: CoreCommentsProvider, sitesProvider: CoreSitesProvider, eventsProvider: CoreEventsProvider) { @@ -58,6 +59,19 @@ export class CoreCommentsCommentsComponent implements OnChanges, OnDestroy { this.fetchData(); } }, sitesProvider.getCurrentSiteId()); + + // Refresh comments if event received. + this.refreshCommentsObserver = eventsProvider.on(CoreCommentsProvider.REFRESH_COMMENTS_EVENT, (data) => { + // Verify these comments need to be updated. + if (this.undefinedOrEqual(data, 'contextLevel') && this.undefinedOrEqual(data, 'instanceId') && + this.undefinedOrEqual(data, 'component') && this.undefinedOrEqual(data, 'itemId') && + this.undefinedOrEqual(data, 'area')) { + + this.doRefresh().catch(() => { + // Ignore errors. + }); + } + }, sitesProvider.getCurrentSiteId()); } /** @@ -77,7 +91,10 @@ export class CoreCommentsCommentsComponent implements OnChanges, OnDestroy { } } - protected fetchData(): void { + /** + * Fetch comments data. + */ + fetchData(): void { if (this.disabled) { return; } @@ -94,6 +111,27 @@ export class CoreCommentsCommentsComponent implements OnChanges, OnDestroy { }); } + /** + * Refresh comments. + * + * @return {Promise} Promise resolved when done. + */ + doRefresh(): Promise { + return this.invalidateComments().then(() => { + return this.fetchData(); + }); + } + + /** + * Invalidate comments data. + * + * @return {Promise} Promise resolved when done. + */ + invalidateComments(): Promise { + return this.commentsProvider.invalidateCommentsData(this.contextLevel, this.instanceId, this.component, this.itemId, + this.area); + } + /** * Opens the comments page. */ @@ -116,5 +154,17 @@ export class CoreCommentsCommentsComponent implements OnChanges, OnDestroy { */ ngOnDestroy(): void { this.updateSiteObserver && this.updateSiteObserver.off(); + this.refreshCommentsObserver && this.refreshCommentsObserver.off(); + } + + /** + * Check if a certain value in data is undefined or equal to this instance value. + * + * @param {any} data Data object. + * @param {string} name Name of the property to check. + * @return {boolean} Whether it's undefined or equal. + */ + protected undefinedOrEqual(data: any, name: string): boolean { + return typeof data[name] == 'undefined' || data[name] == this[name]; } } diff --git a/src/core/comments/providers/comments.ts b/src/core/comments/providers/comments.ts index eb5613c45..16d7c8f95 100644 --- a/src/core/comments/providers/comments.ts +++ b/src/core/comments/providers/comments.ts @@ -25,6 +25,8 @@ import { CoreCommentsOfflineProvider } from './offline'; @Injectable() export class CoreCommentsProvider { + static REFRESH_COMMENTS_EVENT = 'core_comments_refresh_comments'; + 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.