diff --git a/src/addon/messages/pages/group-conversations/group-conversations.ts b/src/addon/messages/pages/group-conversations/group-conversations.ts index b48e9401d..332bae82c 100644 --- a/src/addon/messages/pages/group-conversations/group-conversations.ts +++ b/src/addon/messages/pages/group-conversations/group-conversations.ts @@ -141,8 +141,8 @@ export class AddonMessagesGroupConversationsPage implements OnInit, OnDestroy { conversation.unreadcount = 0; // Conversations changed, invalidate them and refresh unread counts. - this.messagesProvider.invalidateConversations(); - this.messagesProvider.refreshUnreadConversationCounts(); + this.messagesProvider.invalidateConversations(this.siteId); + this.messagesProvider.refreshUnreadConversationCounts(this.siteId); } } }, this.siteId); @@ -251,7 +251,7 @@ export class AddonMessagesGroupConversationsPage implements OnInit, OnDestroy { const promises = []; promises.push(this.fetchConversationCounts()); - promises.push(this.messagesProvider.getContactRequestsCount()); // View updated by the event observer. + promises.push(this.messagesProvider.getContactRequestsCount(this.siteId)); // View updated by the event observer. return Promise.all(promises).then(() => { if (typeof this.favourites.expanded == 'undefined') { @@ -323,7 +323,8 @@ export class AddonMessagesGroupConversationsPage implements OnInit, OnDestroy { promises.push(this.fetchConversationCounts()); if (refreshUnreadCounts) { - promises.push(this.messagesProvider.refreshUnreadConversationCounts()); // View updated by the event observer. + // View updated by event observer. + promises.push(this.messagesProvider.refreshUnreadConversationCounts(this.siteId)); } return Promise.all(promises); @@ -347,10 +348,10 @@ export class AddonMessagesGroupConversationsPage implements OnInit, OnDestroy { offlineMessages; // Get the conversations and, if needed, the offline messages. Always try to get the latest data. - promises.push(this.messagesProvider.invalidateConversations().catch(() => { + promises.push(this.messagesProvider.invalidateConversations(this.siteId).catch(() => { // Shouldn't happen. }).then(() => { - return this.messagesProvider.getConversations(option.type, option.favourites, limitFrom); + return this.messagesProvider.getConversations(option.type, option.favourites, limitFrom, this.siteId); }).then((result) => { data = result; })); @@ -362,7 +363,8 @@ export class AddonMessagesGroupConversationsPage implements OnInit, OnDestroy { promises.push(this.fetchConversationCounts()); if (refreshUnreadCounts) { - promises.push(this.messagesProvider.refreshUnreadConversationCounts()); // View updated by the event observer. + // View updated by the event observer. + promises.push(this.messagesProvider.refreshUnreadConversationCounts(this.siteId)); } } @@ -392,10 +394,10 @@ export class AddonMessagesGroupConversationsPage implements OnInit, OnDestroy { */ protected fetchConversationCounts(): Promise { // Always try to get the latest data. - return this.messagesProvider.invalidateConversationCounts().catch(() => { + return this.messagesProvider.invalidateConversationCounts(this.siteId).catch(() => { // Shouldn't happen. }).then(() => { - return this.messagesProvider.getConversationCounts(); + return this.messagesProvider.getConversationCounts(this.siteId); }).then((counts) => { this.favourites.count = counts.favourites; this.individual.count = counts.individual; @@ -610,7 +612,7 @@ export class AddonMessagesGroupConversationsPage implements OnInit, OnDestroy { refreshData(refresher?: any, refreshUnreadCounts: boolean = true): Promise { // Don't invalidate conversations and so, they always try to get latest data. const promises = [ - this.messagesProvider.invalidateContactRequestsCountCache() + this.messagesProvider.invalidateContactRequestsCountCache(this.siteId) ]; return this.utils.allPromises(promises).finally(() => { diff --git a/src/addon/mod/lesson/pages/player/player.ts b/src/addon/mod/lesson/pages/player/player.ts index c40f6ed8c..10e5e3ab0 100644 --- a/src/addon/mod/lesson/pages/player/player.ts +++ b/src/addon/mod/lesson/pages/player/player.ts @@ -245,7 +245,7 @@ export class AddonModLessonPlayerPage implements OnInit, OnDestroy { if (info.preventaccessreasons && info.preventaccessreasons.length) { // If it's a password protected lesson and we have the password, allow playing it. - const preventReason = this.lessonProvider.getPreventAccessReason(info, !!this.password); + const preventReason = this.lessonProvider.getPreventAccessReason(info, !!this.password, this.review); if (preventReason) { // Lesson cannot be played, show message and go back. return Promise.reject(preventReason.message); diff --git a/src/addon/mod/lesson/providers/lesson.ts b/src/addon/mod/lesson/providers/lesson.ts index 5441b3f3a..a364d1693 100644 --- a/src/addon/mod/lesson/providers/lesson.ts +++ b/src/addon/mod/lesson/providers/lesson.ts @@ -2367,9 +2367,10 @@ export class AddonModLessonProvider { * * @param {any} info Lesson access info. * @param {boolean} [ignorePassword] Whether password protected reason should be ignored (user already entered the password). + * @param {boolean} [isReview] Whether user is reviewing a retake. * @return {any} Prevent access reason. */ - getPreventAccessReason(info: any, ignorePassword?: boolean): any { + getPreventAccessReason(info: any, ignorePassword?: boolean, isReview?: boolean): any { let result; if (info && info.preventaccessreasons) { @@ -2384,6 +2385,8 @@ export class AddonModLessonProvider { // Treat password before all other reasons. result = entry; } + } else if (entry.reason == 'noretake' && isReview) { + // Ignore noretake error when reviewing. } else if (!result) { // Rest of cases, just return any of them. result = entry; diff --git a/src/core/contentlinks/providers/helper.ts b/src/core/contentlinks/providers/helper.ts index ad3d9b6f5..e36e5a20b 100644 --- a/src/core/contentlinks/providers/helper.ts +++ b/src/core/contentlinks/providers/helper.ts @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { Injectable } from '@angular/core'; +import { Injectable, NgZone } from '@angular/core'; import { NavController } from 'ionic-angular'; import { TranslateService } from '@ngx-translate/core'; import { CoreAppProvider } from '@providers/app'; @@ -40,7 +40,7 @@ export class CoreContentLinksHelperProvider { private contentLinksDelegate: CoreContentLinksDelegate, private appProvider: CoreAppProvider, private domUtils: CoreDomUtilsProvider, private urlUtils: CoreUrlUtilsProvider, private translate: TranslateService, private initDelegate: CoreInitDelegate, eventsProvider: CoreEventsProvider, private textUtils: CoreTextUtilsProvider, - private sitePluginsProvider: CoreSitePluginsProvider) { + private sitePluginsProvider: CoreSitePluginsProvider, private zone: NgZone) { this.logger = logger.getInstance('CoreContentLinksHelperProvider'); // Listen for app launched URLs. If we receive one, check if it's a content link. @@ -91,11 +91,15 @@ export class CoreContentLinksHelperProvider { */ goInSite(navCtrl: NavController, pageName: string, pageParams: any, siteId?: string): void { siteId = siteId || this.sitesProvider.getCurrentSiteId(); - if (navCtrl && siteId == this.sitesProvider.getCurrentSiteId()) { - navCtrl.push(pageName, pageParams); - } else { - this.loginHelper.redirect(pageName, pageParams, siteId); - } + + // Execute the code in the Angular zone, so change detection doesn't stop working. + this.zone.run(() => { + if (navCtrl && siteId == this.sitesProvider.getCurrentSiteId()) { + navCtrl.push(pageName, pageParams); + } else { + this.loginHelper.redirect(pageName, pageParams, siteId); + } + }); } /** diff --git a/src/providers/local-notifications.ts b/src/providers/local-notifications.ts index 6c6b7df7c..49ea21312 100644 --- a/src/providers/local-notifications.ts +++ b/src/providers/local-notifications.ts @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { Injectable } from '@angular/core'; +import { Injectable, NgZone } from '@angular/core'; import { Platform, Alert, AlertController } from 'ionic-angular'; import { LocalNotifications, ILocalNotification } from '@ionic-native/local-notifications'; import { Push } from '@ionic-native/push'; @@ -105,7 +105,7 @@ export class CoreLocalNotificationsProvider { constructor(logger: CoreLoggerProvider, private localNotifications: LocalNotifications, private platform: Platform, private appProvider: CoreAppProvider, private utils: CoreUtilsProvider, private configProvider: CoreConfigProvider, private textUtils: CoreTextUtilsProvider, private translate: TranslateService, private alertCtrl: AlertController, - eventsProvider: CoreEventsProvider, private push: Push) { + eventsProvider: CoreEventsProvider, private push: Push, private zone: NgZone) { this.logger = logger.getInstance('CoreLocalNotificationsProvider'); this.appDB = appProvider.getDB(); @@ -327,12 +327,15 @@ export class CoreLocalNotificationsProvider { * @param {any} data Data received by the notification. */ notifyClick(data: any): void { - const component = data.component; - if (component) { - if (this.observables[component]) { - this.observables[component].next(data); + // Execute the code in the Angular zone, so change detection doesn't stop working. + this.zone.run(() => { + const component = data.component; + if (component) { + if (this.observables[component]) { + this.observables[component].next(data); + } } - } + }); } /**