From fe494fe700d1709e28c8654c834967d77d931978 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Thu, 16 Aug 2018 12:20:23 +0200 Subject: [PATCH] MOBILE-2080 forum: Update badge --- src/addon/mod/forum/components/index/index.ts | 2 +- .../mod/forum/pages/discussion/discussion.ts | 8 ++- .../pages/new-discussion/new-discussion.ts | 4 +- src/addon/mod/forum/providers/forum.ts | 1 + .../mod/forum/providers/module-handler.ts | 58 +++++++++++++++---- .../mod/forum/providers/prefetch-handler.ts | 18 ++++++ .../actions/addon-notifications-actions.html | 4 +- .../components/module/core-course-module.html | 4 +- src/core/course/components/module/module.ts | 1 + src/core/course/providers/module-delegate.ts | 11 ++++ 10 files changed, 94 insertions(+), 17 deletions(-) diff --git a/src/addon/mod/forum/components/index/index.ts b/src/addon/mod/forum/components/index/index.ts index 4755aa87c..72993f242 100644 --- a/src/addon/mod/forum/components/index/index.ts +++ b/src/addon/mod/forum/components/index/index.ts @@ -84,7 +84,7 @@ export class AddonModForumIndexComponent extends CoreCourseModuleMainActivityCom this.newDiscObserver = this.eventsProvider.on(AddonModForumProvider.NEW_DISCUSSION_EVENT, this.eventReceived.bind(this)); this.replyObserver = this.eventsProvider.on(AddonModForumProvider.REPLY_DISCUSSION_EVENT, this.eventReceived.bind(this)); - // Select the curren opened discussion. + // Select the current opened discussion. this.viewDiscObserver = this.eventsProvider.on(AddonModForumProvider.VIEW_DISCUSSION_EVENT, (data) => { if (this.forum && this.forum.id == data.forumId) { this.selectedDiscussion = this.splitviewCtrl.isOn() ? data.discussion : 0; diff --git a/src/addon/mod/forum/pages/discussion/discussion.ts b/src/addon/mod/forum/pages/discussion/discussion.ts index 15e5d64d8..a063e5367 100644 --- a/src/addon/mod/forum/pages/discussion/discussion.ts +++ b/src/addon/mod/forum/pages/discussion/discussion.ts @@ -145,7 +145,7 @@ export class AddonModForumDiscussionPage implements OnDestroy { // Trigger view event, to highlight the current opened discussion in the split view. this.eventsProvider.trigger(AddonModForumProvider.VIEW_DISCUSSION_EVENT, { forumId: this.forumId, - discussion: this.discussionId, + discussion: this.discussionId }, this.sitesProvider.getCurrentSiteId()); } @@ -297,6 +297,12 @@ export class AddonModForumDiscussionPage implements OnDestroy { // // Add log in Moodle and mark unread posts as readed. this.forumProvider.logDiscussionView(this.discussionId).catch(() => { // Ignore errors. + }).finally(() => { + // Trigger mark read posts. + this.eventsProvider.trigger(AddonModForumProvider.MARK_READ_EVENT, { + courseId: this.courseId, + moduleId: this.cmId + }, this.sitesProvider.getCurrentSiteId()); }); } }); diff --git a/src/addon/mod/forum/pages/new-discussion/new-discussion.ts b/src/addon/mod/forum/pages/new-discussion/new-discussion.ts index abc39de32..e5bc20b4e 100644 --- a/src/addon/mod/forum/pages/new-discussion/new-discussion.ts +++ b/src/addon/mod/forum/pages/new-discussion/new-discussion.ts @@ -117,7 +117,7 @@ export class AddonModForumNewDiscussionPage implements OnDestroy { // Trigger view event, to highlight the current opened discussion in the split view. this.eventsProvider.trigger(AddonModForumProvider.VIEW_DISCUSSION_EVENT, { forumId: this.forumId, - discussion: -this.timeCreated, + discussion: -this.timeCreated }, this.sitesProvider.getCurrentSiteId()); } @@ -378,7 +378,7 @@ export class AddonModForumNewDiscussionPage implements OnDestroy { // Trigger view event, to highlight the current opened discussion in the split view. this.eventsProvider.trigger(AddonModForumProvider.VIEW_DISCUSSION_EVENT, { forumId: this.forumId, - discussion: 0, + discussion: 0 }, this.sitesProvider.getCurrentSiteId()); } else { this.originalData = null; // Avoid asking for confirmation. diff --git a/src/addon/mod/forum/providers/forum.ts b/src/addon/mod/forum/providers/forum.ts index cdbe517d3..f386ac855 100644 --- a/src/addon/mod/forum/providers/forum.ts +++ b/src/addon/mod/forum/providers/forum.ts @@ -32,6 +32,7 @@ export class AddonModForumProvider { static NEW_DISCUSSION_EVENT = 'addon_mod_forum_new_discussion'; static REPLY_DISCUSSION_EVENT = 'addon_mod_forum_reply_discussion'; static VIEW_DISCUSSION_EVENT = 'addon_mod_forum_view_discussion'; + static MARK_READ_EVENT = 'addon_mod_forum_mark_read'; protected ROOT_CACHE_KEY = 'mmaModForum:'; diff --git a/src/addon/mod/forum/providers/module-handler.ts b/src/addon/mod/forum/providers/module-handler.ts index 0b42c9a51..fef8ce605 100644 --- a/src/addon/mod/forum/providers/module-handler.ts +++ b/src/addon/mod/forum/providers/module-handler.ts @@ -15,10 +15,12 @@ import { Injectable } from '@angular/core'; import { NavController, NavOptions } from 'ionic-angular'; import { TranslateService } from '@ngx-translate/core'; -import { AddonModForumIndexComponent } from '../components/index/index'; +import { CoreEventsProvider } from '@providers/events'; +import { CoreSitesProvider } from '@providers/sites'; import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@core/course/providers/module-delegate'; import { CoreCourseProvider } from '@core/course/providers/course'; import { AddonModForumProvider } from './forum'; +import { AddonModForumIndexComponent } from '../components/index/index'; /** * Handler to support forum modules. @@ -29,7 +31,8 @@ export class AddonModForumModuleHandler implements CoreCourseModuleHandler { modName = 'forum'; constructor(private courseProvider: CoreCourseProvider, private forumProvider: AddonModForumProvider, - private translate: TranslateService) { } + private translate: TranslateService, private eventsProvider: CoreEventsProvider, + private sitesProvider: CoreSitesProvider) {} /** * Check if the handler is enabled on a site level. @@ -49,7 +52,7 @@ export class AddonModForumModuleHandler implements CoreCourseModuleHandler { * @return {CoreCourseModuleHandlerData} Data to render the module. */ getData(module: any, courseId: number, sectionId: number): CoreCourseModuleHandlerData { - const data: CoreCourseModuleHandlerData = { + const data: CoreCourseModuleHandlerData = { icon: this.courseProvider.getModuleIconSrc('forum'), title: module.name, class: 'addon-mod_forum-handler', @@ -59,13 +62,17 @@ export class AddonModForumModuleHandler implements CoreCourseModuleHandler { } }; - // Handle unread posts. - this.forumProvider.getForum(courseId, module.id).then((forumData) => { - data.extraBadge = forumData.unreadpostscount ? this.translate.instant('addon.mod_forum.unreadpostsnumber', - {$a : forumData.unreadpostscount }) : ''; - }).catch(() => { - // Ignore errors. - }); + this.updateExtraBadge(data, courseId, module.id); + + const event = this.eventsProvider.on(AddonModForumProvider.MARK_READ_EVENT, (eventData) => { + if (eventData.courseId == courseId && eventData.moduleId == module.id) { + this.updateExtraBadge(data, eventData.courseId, eventData.moduleId, eventData.siteId); + } + }, this.sitesProvider.getCurrentSiteId()); + + data.onDestroy = (): void => { + event && event.off(); + }; return data; } @@ -91,4 +98,35 @@ export class AddonModForumModuleHandler implements CoreCourseModuleHandler { displayRefresherInSingleActivity(): boolean { return false; } + + /** + * Triggers an update for the extra badge text. + * + * @param {CoreCourseModuleHandlerData} data Course Module Handler data. + * @param {number} courseId Course ID. + * @param {number} moduleId Course module ID. + * @param {string} [siteId] Site ID. If not defined, current site. + */ + updateExtraBadge(data: CoreCourseModuleHandlerData, courseId: number, moduleId: number, siteId?: string): void { + siteId = siteId || this.sitesProvider.getCurrentSiteId(); + if (!siteId) { + return; + } + + data.extraBadge = this.translate.instant('core.loading'); + data.extraBadgeColor = 'light'; + + this.forumProvider.invalidateForumData(courseId).finally(() => { + // Handle unread posts. + this.forumProvider.getForum(courseId, moduleId, siteId).then((forumData) => { + data.extraBadgeColor = ''; + data.extraBadge = forumData.unreadpostscount ? this.translate.instant('addon.mod_forum.unreadpostsnumber', + {$a : forumData.unreadpostscount }) : ''; + }).catch(() => { + data.extraBadgeColor = ''; + data.extraBadge = ''; + // Ignore errors. + }); + }); + } } diff --git a/src/addon/mod/forum/providers/prefetch-handler.ts b/src/addon/mod/forum/providers/prefetch-handler.ts index 81ba80633..e8b8fda15 100644 --- a/src/addon/mod/forum/providers/prefetch-handler.ts +++ b/src/addon/mod/forum/providers/prefetch-handler.ts @@ -132,6 +132,24 @@ export class AddonModForumPrefetchHandler extends CoreCourseActivityPrefetchHand return this.forumProvider.invalidateContent(moduleId, courseId); } + /** + * Invalidate WS calls needed to determine module status (usually, to check if module is downloadable). + * It doesn't need to invalidate check updates. It should NOT invalidate files nor all the prefetched data. + * + * @param {any} module Module. + * @param {number} courseId Course ID the module belongs to. + * @return {Promise} Promise resolved when invalidated. + */ + invalidateModule(module: any, courseId: number): Promise { + // Invalidate forum data to recalculate unread message count badge. + const promises = []; + + promises.push(this.forumProvider.invalidateForumData(courseId)); + promises.push(this.courseProvider.invalidateModule(module.id)); + + return Promise.all(promises); + } + /** * Prefetch a module. * diff --git a/src/addon/notifications/components/actions/addon-notifications-actions.html b/src/addon/notifications/components/actions/addon-notifications-actions.html index 7d69e94bd..14425705d 100644 --- a/src/addon/notifications/components/actions/addon-notifications-actions.html +++ b/src/addon/notifications/components/actions/addon-notifications-actions.html @@ -1,6 +1,6 @@ - + - diff --git a/src/core/course/components/module/core-course-module.html b/src/core/course/components/module/core-course-module.html index 9aa9ff37c..15a621e17 100644 --- a/src/core/course/components/module/core-course-module.html +++ b/src/core/course/components/module/core-course-module.html @@ -31,7 +31,9 @@
- + + + {{ 'core.course.hiddenfromstudents' | translate }}
diff --git a/src/core/course/components/module/module.ts b/src/core/course/components/module/module.ts index 3ea6e92bc..1690ed303 100644 --- a/src/core/course/components/module/module.ts +++ b/src/core/course/components/module/module.ts @@ -173,6 +173,7 @@ export class CoreCourseModuleComponent implements OnInit, OnDestroy { */ ngOnDestroy(): void { this.statusObserver && this.statusObserver.off(); + this.module && this.module.handlerData && this.module.handlerData.onDestroy && this.module.handlerData.onDestroy(); this.isDestroyed = true; } } diff --git a/src/core/course/providers/module-delegate.ts b/src/core/course/providers/module-delegate.ts index a61f3dbda..b367efbf1 100644 --- a/src/core/course/providers/module-delegate.ts +++ b/src/core/course/providers/module-delegate.ts @@ -91,6 +91,12 @@ export interface CoreCourseModuleHandlerData { */ extraBadge?: string; + /** + * The color of the extra badge. Default: primary. + * @type {string} + */ + extraBadgeColor?: string; + /** * Whether to display a button to download/refresh the module if it's downloadable. * If it's set to true, the app will show a download/refresh button when needed and will handle the download of the @@ -128,6 +134,11 @@ export interface CoreCourseModuleHandlerData { * @param {string} status Module status. */ updateStatus?(status: string): void; + + /** + * On Destroy function in case it's needed. + */ + onDestroy?(): void; } /**