commit
756fce9a84
|
@ -133,6 +133,7 @@ export class AddonModLessonIndexComponent extends CoreCourseModuleMainActivityCo
|
||||||
this.accessInfo = info;
|
this.accessInfo = info;
|
||||||
this.canManage = info.canmanage;
|
this.canManage = info.canmanage;
|
||||||
this.canViewReports = info.canviewreports;
|
this.canViewReports = info.canviewreports;
|
||||||
|
this.preventMessages = [];
|
||||||
|
|
||||||
if (this.lessonProvider.isLessonOffline(this.lesson)) {
|
if (this.lessonProvider.isLessonOffline(this.lesson)) {
|
||||||
// Handle status.
|
// Handle status.
|
||||||
|
@ -162,7 +163,8 @@ export class AddonModLessonIndexComponent extends CoreCourseModuleMainActivityCo
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info.preventaccessreasons && info.preventaccessreasons.length) {
|
if (info.preventaccessreasons && info.preventaccessreasons.length) {
|
||||||
const askPassword = info.preventaccessreasons.length == 1 && this.lessonProvider.isPasswordProtected(info);
|
let preventReason = this.lessonProvider.getPreventAccessReason(info, false);
|
||||||
|
const askPassword = preventReason.reason == 'passwordprotectedlesson';
|
||||||
|
|
||||||
if (askPassword) {
|
if (askPassword) {
|
||||||
// The lesson requires a password. Check if there is one in memory or DB.
|
// The lesson requires a password. Check if there is one in memory or DB.
|
||||||
|
@ -171,15 +173,21 @@ export class AddonModLessonIndexComponent extends CoreCourseModuleMainActivityCo
|
||||||
|
|
||||||
promises.push(promise.then((password) => {
|
promises.push(promise.then((password) => {
|
||||||
return this.validatePassword(password);
|
return this.validatePassword(password);
|
||||||
|
}).then(() => {
|
||||||
|
// Now that we have the password, get the access reason again ignoring the password.
|
||||||
|
preventReason = this.lessonProvider.getPreventAccessReason(info, true);
|
||||||
|
if (preventReason) {
|
||||||
|
this.preventMessages = [preventReason];
|
||||||
|
}
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
// No password or the validation failed. Show password form.
|
// No password or the validation failed. Show password form.
|
||||||
this.askPassword = true;
|
this.askPassword = true;
|
||||||
this.preventMessages = info.preventaccessreasons;
|
this.preventMessages = [preventReason];
|
||||||
lessonReady = false;
|
lessonReady = false;
|
||||||
}));
|
}));
|
||||||
} else {
|
} else {
|
||||||
// Lesson cannot be started.
|
// Lesson cannot be started.
|
||||||
this.preventMessages = info.preventaccessreasons;
|
this.preventMessages = [preventReason];
|
||||||
lessonReady = false;
|
lessonReady = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -293,7 +301,6 @@ export class AddonModLessonIndexComponent extends CoreCourseModuleMainActivityCo
|
||||||
*/
|
*/
|
||||||
protected lessonReady(refresh?: boolean): void {
|
protected lessonReady(refresh?: boolean): void {
|
||||||
this.askPassword = false;
|
this.askPassword = false;
|
||||||
this.preventMessages = [];
|
|
||||||
this.leftDuringTimed = this.hasOffline || this.lessonProvider.leftDuringTimed(this.accessInfo);
|
this.leftDuringTimed = this.hasOffline || this.lessonProvider.leftDuringTimed(this.accessInfo);
|
||||||
|
|
||||||
if (this.password) {
|
if (this.password) {
|
||||||
|
@ -524,6 +531,12 @@ export class AddonModLessonIndexComponent extends CoreCourseModuleMainActivityCo
|
||||||
// Password validated.
|
// Password validated.
|
||||||
this.lessonReady(false);
|
this.lessonReady(false);
|
||||||
|
|
||||||
|
// Now that we have the password, get the access reason again ignoring the password.
|
||||||
|
const preventReason = this.lessonProvider.getPreventAccessReason(this.accessInfo, true);
|
||||||
|
if (preventReason) {
|
||||||
|
this.preventMessages = [preventReason];
|
||||||
|
}
|
||||||
|
|
||||||
// Log view now that we have the password.
|
// Log view now that we have the password.
|
||||||
this.logView();
|
this.logView();
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
|
|
|
@ -245,9 +245,10 @@ export class AddonModLessonPlayerPage implements OnInit, OnDestroy {
|
||||||
|
|
||||||
if (info.preventaccessreasons && info.preventaccessreasons.length) {
|
if (info.preventaccessreasons && info.preventaccessreasons.length) {
|
||||||
// If it's a password protected lesson and we have the password, allow playing it.
|
// If it's a password protected lesson and we have the password, allow playing it.
|
||||||
if (!this.password || info.preventaccessreasons.length > 1 || !this.lessonProvider.isPasswordProtected(info)) {
|
const preventReason = this.lessonProvider.getPreventAccessReason(info, !!this.password);
|
||||||
|
if (preventReason) {
|
||||||
// Lesson cannot be played, show message and go back.
|
// Lesson cannot be played, show message and go back.
|
||||||
return Promise.reject(info.preventaccessreasons[0].message);
|
return Promise.reject(preventReason.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2335,6 +2335,38 @@ export class AddonModLessonProvider {
|
||||||
return this.ROOT_CACHE_KEY + 'userRetake:' + lessonId;
|
return this.ROOT_CACHE_KEY + 'userRetake:' + lessonId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the prevent access reason to display for a certain lesson.
|
||||||
|
*
|
||||||
|
* @param {any} info Lesson access info.
|
||||||
|
* @param {boolean} [ignorePassword] Whether password protected reason should be ignored (user already entered the password).
|
||||||
|
* @return {any} Prevent access reason.
|
||||||
|
*/
|
||||||
|
getPreventAccessReason(info: any, ignorePassword?: boolean): any {
|
||||||
|
let result;
|
||||||
|
|
||||||
|
if (info && info.preventaccessreasons) {
|
||||||
|
for (let i = 0; i < info.preventaccessreasons.length; i++) {
|
||||||
|
const entry = info.preventaccessreasons[i];
|
||||||
|
|
||||||
|
if (entry.reason == 'lessonopen' || entry.reason == 'lessonclosed') {
|
||||||
|
// Time restrictions are the most prioritary, return it.
|
||||||
|
return entry;
|
||||||
|
} else if (entry.reason == 'passwordprotectedlesson') {
|
||||||
|
if (!ignorePassword) {
|
||||||
|
// Treat password before all other reasons.
|
||||||
|
result = entry;
|
||||||
|
}
|
||||||
|
} else if (!result) {
|
||||||
|
// Rest of cases, just return any of them.
|
||||||
|
result = entry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if a jump is correct.
|
* Check if a jump is correct.
|
||||||
* Based in Moodle's jumpto_is_correct.
|
* Based in Moodle's jumpto_is_correct.
|
||||||
|
|
|
@ -1273,7 +1273,9 @@ export class CoreSite {
|
||||||
return this.domUtils.showAlert(this.translate.instant('core.notice'), alertMessage, undefined, 3000).then((alert) => {
|
return this.domUtils.showAlert(this.translate.instant('core.notice'), alertMessage, undefined, 3000).then((alert) => {
|
||||||
|
|
||||||
return new Promise<InAppBrowserObject | void>((resolve, reject): void => {
|
return new Promise<InAppBrowserObject | void>((resolve, reject): void => {
|
||||||
alert.onDidDismiss(() => {
|
const subscription = alert.didDismiss.subscribe(() => {
|
||||||
|
subscription && subscription.unsubscribe();
|
||||||
|
|
||||||
if (inApp) {
|
if (inApp) {
|
||||||
resolve(this.utils.openInApp(url, options));
|
resolve(this.utils.openInApp(url, options));
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -697,7 +697,9 @@ export class CoreLoginHelperProvider {
|
||||||
*/
|
*/
|
||||||
openChangePassword(siteUrl: string, error: string): void {
|
openChangePassword(siteUrl: string, error: string): void {
|
||||||
this.domUtils.showAlert(this.translate.instant('core.notice'), error, undefined, 3000).then((alert) => {
|
this.domUtils.showAlert(this.translate.instant('core.notice'), error, undefined, 3000).then((alert) => {
|
||||||
alert.onDidDismiss(() => {
|
const subscription = alert.didDismiss.subscribe(() => {
|
||||||
|
subscription && subscription.unsubscribe();
|
||||||
|
|
||||||
this.utils.openInApp(siteUrl + '/login/change_password.php');
|
this.utils.openInApp(siteUrl + '/login/change_password.php');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Component, OnDestroy, ViewChild } from '@angular/core';
|
import { Component, OnDestroy, ViewChild, ChangeDetectorRef } from '@angular/core';
|
||||||
import { IonicPage, NavController, NavParams } from 'ionic-angular';
|
import { IonicPage, NavController, NavParams } from 'ionic-angular';
|
||||||
import { CoreSitesProvider } from '@providers/sites';
|
import { CoreSitesProvider } from '@providers/sites';
|
||||||
import { CoreEventsProvider } from '@providers/events';
|
import { CoreEventsProvider } from '@providers/events';
|
||||||
|
@ -42,7 +42,7 @@ export class CoreMainMenuPage implements OnDestroy {
|
||||||
@ViewChild('mainTabs') mainTabs: CoreIonTabsComponent;
|
@ViewChild('mainTabs') mainTabs: CoreIonTabsComponent;
|
||||||
|
|
||||||
constructor(private menuDelegate: CoreMainMenuDelegate, private sitesProvider: CoreSitesProvider, navParams: NavParams,
|
constructor(private menuDelegate: CoreMainMenuDelegate, private sitesProvider: CoreSitesProvider, navParams: NavParams,
|
||||||
private navCtrl: NavController, private eventsProvider: CoreEventsProvider) {
|
private navCtrl: NavController, private eventsProvider: CoreEventsProvider, private cdr: ChangeDetectorRef) {
|
||||||
|
|
||||||
// Check if the menu was loaded with a redirect.
|
// Check if the menu was loaded with a redirect.
|
||||||
const redirectPage = navParams.get('redirectPage');
|
const redirectPage = navParams.get('redirectPage');
|
||||||
|
@ -138,6 +138,9 @@ export class CoreMainMenuPage implements OnDestroy {
|
||||||
this.redirectParams = data.redirectParams;
|
this.redirectParams = data.redirectParams;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Force change detection, otherwise sometimes the tab was selected before the params were applied.
|
||||||
|
this.cdr.detectChanges();
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
// Let the tab load the params before navigating.
|
// Let the tab load the params before navigating.
|
||||||
this.mainTabs.selectTabRootByIndex(i + 1);
|
this.mainTabs.selectTabRootByIndex(i + 1);
|
||||||
|
|
|
@ -25,6 +25,24 @@ import { CoreConfigProvider } from '../config';
|
||||||
import { CoreUrlUtilsProvider } from './url';
|
import { CoreUrlUtilsProvider } from './url';
|
||||||
import { CoreConstants } from '@core/constants';
|
import { CoreConstants } from '@core/constants';
|
||||||
import { Md5 } from 'ts-md5/dist/md5';
|
import { Md5 } from 'ts-md5/dist/md5';
|
||||||
|
import { Subject } from 'rxjs';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface that defines an extension of the Ionic Alert class, to support multiple listeners.
|
||||||
|
*/
|
||||||
|
export interface CoreAlert extends Alert {
|
||||||
|
/**
|
||||||
|
* Observable that will notify when the alert is dismissed.
|
||||||
|
* @type {Subject<{data: any, role: string}>}
|
||||||
|
*/
|
||||||
|
didDismiss: Subject<{data: any, role: string}>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Observable that will notify when the alert will be dismissed.
|
||||||
|
* @type {Subject<{data: any, role: string}>}
|
||||||
|
*/
|
||||||
|
willDismiss: Subject<{data: any, role: string}>;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* "Utils" service with helper functions for UI, DOM elements and HTML code.
|
* "Utils" service with helper functions for UI, DOM elements and HTML code.
|
||||||
|
@ -886,9 +904,9 @@ export class CoreDomUtilsProvider {
|
||||||
* @param {string} message Message to show.
|
* @param {string} message Message to show.
|
||||||
* @param {string} [buttonText] Text of the button.
|
* @param {string} [buttonText] Text of the button.
|
||||||
* @param {number} [autocloseTime] Number of milliseconds to wait to close the modal. If not defined, modal won't be closed.
|
* @param {number} [autocloseTime] Number of milliseconds to wait to close the modal. If not defined, modal won't be closed.
|
||||||
* @return {Promise<Alert>} Promise resolved with the alert modal.
|
* @return {Promise<CoreAlert>} Promise resolved with the alert modal.
|
||||||
*/
|
*/
|
||||||
showAlert(title: string, message: string, buttonText?: string, autocloseTime?: number): Promise<Alert> {
|
showAlert(title: string, message: string, buttonText?: string, autocloseTime?: number): Promise<CoreAlert> {
|
||||||
const hasHTMLTags = this.textUtils.hasHTMLTags(message);
|
const hasHTMLTags = this.textUtils.hasHTMLTags(message);
|
||||||
let promise;
|
let promise;
|
||||||
|
|
||||||
|
@ -907,7 +925,7 @@ export class CoreDomUtilsProvider {
|
||||||
return this.displayedAlerts[alertId];
|
return this.displayedAlerts[alertId];
|
||||||
}
|
}
|
||||||
|
|
||||||
const alert = this.alertCtrl.create({
|
const alert: CoreAlert = <any> this.alertCtrl.create({
|
||||||
title: title,
|
title: title,
|
||||||
message: message,
|
message: message,
|
||||||
buttons: [buttonText || this.translate.instant('core.ok')]
|
buttons: [buttonText || this.translate.instant('core.ok')]
|
||||||
|
@ -924,8 +942,19 @@ export class CoreDomUtilsProvider {
|
||||||
// Store the alert and remove it when dismissed.
|
// Store the alert and remove it when dismissed.
|
||||||
this.displayedAlerts[alertId] = alert;
|
this.displayedAlerts[alertId] = alert;
|
||||||
|
|
||||||
alert.onDidDismiss(() => {
|
// Define the observables to extend the Alert class. This will allow several callbacks instead of just one.
|
||||||
|
alert.didDismiss = new Subject();
|
||||||
|
alert.willDismiss = new Subject();
|
||||||
|
|
||||||
|
// Set the callbacks to trigger an observable event.
|
||||||
|
alert.onDidDismiss((data: any, role: string) => {
|
||||||
delete this.displayedAlerts[alertId];
|
delete this.displayedAlerts[alertId];
|
||||||
|
|
||||||
|
alert.didDismiss.next({data: data, role: role});
|
||||||
|
});
|
||||||
|
|
||||||
|
alert.onWillDismiss((data: any, role: string) => {
|
||||||
|
alert.willDismiss.next({data: data, role: role});
|
||||||
});
|
});
|
||||||
|
|
||||||
if (autocloseTime > 0) {
|
if (autocloseTime > 0) {
|
||||||
|
|
|
@ -8,6 +8,7 @@ information provided here is intended especially for developers.
|
||||||
- The value of the constant CoreCourseProvider.ALL_SECTIONS_ID has changed from -1 to -2.
|
- The value of the constant CoreCourseProvider.ALL_SECTIONS_ID has changed from -1 to -2.
|
||||||
- Use of completionstatus on the module object has been deprecated, use completiondata instead.
|
- Use of completionstatus on the module object has been deprecated, use completiondata instead.
|
||||||
- The function CoreSitesProvider.loadSite has changed, now it will trigger SESSION_EXPIRED event if the site is logged out. Its params and return value have changed.
|
- The function CoreSitesProvider.loadSite has changed, now it will trigger SESSION_EXPIRED event if the site is logged out. Its params and return value have changed.
|
||||||
|
- When using CoreDomUtils.showAlert, please use alert.didDismiss.subscribe() instead of alert.onDidDismiss().
|
||||||
- The following strings have been deprecated:
|
- The following strings have been deprecated:
|
||||||
core.dfdaymonthyear. Please use core.strftimedatefullshort instead.
|
core.dfdaymonthyear. Please use core.strftimedatefullshort instead.
|
||||||
core.dfdayweekmonth. Please use core.strftimedayshort instead.
|
core.dfdayweekmonth. Please use core.strftimedayshort instead.
|
||||||
|
|
Loading…
Reference in New Issue