From 5533c39288706def9fd5f9d0881fde9eb5eb8a0f Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Wed, 28 Aug 2019 10:38:44 +0200 Subject: [PATCH 1/4] 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. From 5794bade90fdf718fca15834676e49461b961ed6 Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Wed, 28 Aug 2019 10:52:06 +0200 Subject: [PATCH 2/4] MOBILE-3068 blog: Fix entries disappearing on PTR --- src/addon/blog/components/entries/entries.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/addon/blog/components/entries/entries.ts b/src/addon/blog/components/entries/entries.ts index 89a5b0917..aa66beaef 100644 --- a/src/addon/blog/components/entries/entries.ts +++ b/src/addon/blog/components/entries/entries.ts @@ -223,7 +223,7 @@ export class AddonBlogEntriesComponent implements OnInit { this.filter['userid'] = this.currentUserId; promises.push(this.blogProvider.invalidateEntries(this.filter)); - if (!this.showMyEntriesToggle) { + if (!this.onlyMyEntries) { delete this.filter['userid']; } From 43d6839a8d78d7570e9c84044f86c780a583f5ec Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Wed, 28 Aug 2019 11:20:07 +0200 Subject: [PATCH 3/4] MOBILE-3068 comments: Open comments in new page if split view --- .../addon-mod-assign-submission-comments.html | 2 +- .../submission/comments/component/comments.ts | 4 ++-- .../comments/components/comments/comments.ts | 18 ++++++++++++++---- .../components/comments/core-comments.html | 2 +- 4 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/addon/mod/assign/submission/comments/component/addon-mod-assign-submission-comments.html b/src/addon/mod/assign/submission/comments/component/addon-mod-assign-submission-comments.html index be2ba466f..8040cdfeb 100644 --- a/src/addon/mod/assign/submission/comments/component/addon-mod-assign-submission-comments.html +++ b/src/addon/mod/assign/submission/comments/component/addon-mod-assign-submission-comments.html @@ -1,4 +1,4 @@ - +

{{plugin.name}}

diff --git a/src/addon/mod/assign/submission/comments/component/comments.ts b/src/addon/mod/assign/submission/comments/component/comments.ts index 98c8be9e0..bd6bb57c2 100644 --- a/src/addon/mod/assign/submission/comments/component/comments.ts +++ b/src/addon/mod/assign/submission/comments/component/comments.ts @@ -48,7 +48,7 @@ export class AddonModAssignSubmissionCommentsComponent extends AddonModAssignSub /** * Show the comments. */ - showComments(): void { - this.commentsComponent && this.commentsComponent.openComments(); + showComments(e?: Event): void { + this.commentsComponent && this.commentsComponent.openComments(e); } } diff --git a/src/core/comments/components/comments/comments.ts b/src/core/comments/components/comments/comments.ts index 6e32bc710..6bbe34fc4 100644 --- a/src/core/comments/components/comments/comments.ts +++ b/src/core/comments/components/comments/comments.ts @@ -12,11 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { Component, EventEmitter, Input, OnChanges, OnDestroy, Output, SimpleChange } from '@angular/core'; +import { Component, EventEmitter, Input, OnChanges, OnDestroy, Output, SimpleChange, Optional } from '@angular/core'; import { NavController } from 'ionic-angular'; import { CoreCommentsProvider } from '../../providers/comments'; import { CoreEventsProvider } from '@providers/events'; import { CoreSitesProvider } from '@providers/sites'; +import { CoreSplitViewComponent } from '@components/split-view/split-view'; /** * Component that displays the count of comments. @@ -44,7 +45,9 @@ export class CoreCommentsCommentsComponent implements OnChanges, OnDestroy { protected refreshCommentsObserver; constructor(private navCtrl: NavController, private commentsProvider: CoreCommentsProvider, - sitesProvider: CoreSitesProvider, eventsProvider: CoreEventsProvider) { + sitesProvider: CoreSitesProvider, eventsProvider: CoreEventsProvider, + @Optional() private svComponent: CoreSplitViewComponent) { + this.onLoading = new EventEmitter(); this.disabled = this.commentsProvider.areCommentsDisabledInSite(); @@ -135,10 +138,17 @@ export class CoreCommentsCommentsComponent implements OnChanges, OnDestroy { /** * Opens the comments page. */ - openComments(): void { + openComments(e?: Event): void { + if (e) { + e.preventDefault(); + e.stopPropagation(); + } + if (!this.disabled && !this.countError) { // Open a new state with the interpolated contents. - this.navCtrl.push('CoreCommentsViewerPage', { + const navCtrl = this.svComponent ? this.svComponent.getMasterNav() : this.navCtrl; + + navCtrl.push('CoreCommentsViewerPage', { contextLevel: this.contextLevel, instanceId: this.instanceId, componentName: this.component, diff --git a/src/core/comments/components/comments/core-comments.html b/src/core/comments/components/comments/core-comments.html index 2c2c8efeb..4375edc5a 100644 --- a/src/core/comments/components/comments/core-comments.html +++ b/src/core/comments/components/comments/core-comments.html @@ -1,5 +1,5 @@ -
+
{{ 'core.comments.commentscount' | translate : {'$a': commentsCount} }}
From 344a3c639f999b23886dfe33cbb933755d11738d Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Wed, 28 Aug 2019 12:40:43 +0200 Subject: [PATCH 4/4] MOBILE-3068 blocks: Don't use phantom tabs in title blocks --- .../components/only-title-block/only-title-block.ts | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/core/block/components/only-title-block/only-title-block.ts b/src/core/block/components/only-title-block/only-title-block.ts index a128c44d1..2c1145003 100644 --- a/src/core/block/components/only-title-block/only-title-block.ts +++ b/src/core/block/components/only-title-block/only-title-block.ts @@ -13,8 +13,9 @@ // limitations under the License. import { Injector, OnInit, Component } from '@angular/core'; +import { NavController } from 'ionic-angular'; import { CoreBlockBaseComponent } from '../../classes/base-block-component'; -import { CoreLoginHelperProvider } from '@core/login/providers/helper'; +import { CoreContentLinksHelperProvider } from '@core/contentlinks/providers/helper'; /** * Component to render blocks with only a title and link. @@ -25,11 +26,8 @@ import { CoreLoginHelperProvider } from '@core/login/providers/helper'; }) export class CoreBlockOnlyTitleComponent extends CoreBlockBaseComponent implements OnInit { - protected loginHelper: CoreLoginHelperProvider; - - constructor(injector: Injector) { + constructor(injector: Injector, protected navCtrl: NavController, protected linkHelper: CoreContentLinksHelperProvider) { super(injector, 'CoreBlockOnlyTitleComponent'); - this.loginHelper = injector.get(CoreLoginHelperProvider); } /** @@ -45,6 +43,6 @@ export class CoreBlockOnlyTitleComponent extends CoreBlockBaseComponent impleme * Go to the block page. */ gotoBlock(): void { - this.loginHelper.redirect(this.link, this.linkParams); + this.linkHelper.goInSite(this.navCtrl, this.link, this.linkParams, undefined, true); } }