Merge pull request #2986 from dpalou/MOBILE-3903

Mobile 3903
main
Pau Ferrer Ocaña 2021-11-04 15:55:21 +01:00 committed by GitHub
commit 5722067cee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 79 additions and 79 deletions

View File

@ -90,7 +90,7 @@ export class CoreCoursesCourseLinkHandlerService extends CoreContentLinksHandler
return;
} else {
this.actionEnrol(courseId, url, pageParams).catch(() => {
this.actionOpen(courseId, url, pageParams).catch(() => {
// Ignore errors.
});
}
@ -124,14 +124,14 @@ export class CoreCoursesCourseLinkHandlerService extends CoreContentLinksHandler
}
/**
* Action to perform when an enrol link is clicked.
* Try to open the course, asking the user to enrol if needed.
*
* @param courseId Course ID.
* @param url Treated URL.
* @param pageParams Params to send to the new page.
* @return Promise resolved when done.
*/
protected async actionEnrol(courseId: number, url: string, pageParams: Params): Promise<void> {
protected async actionOpen(courseId: number, url: string, pageParams: Params): Promise<void> {
const modal = await CoreDomUtils.showModalLoading();
let course: CoreCourseAnyCourseData | { id: number } | undefined;
@ -167,95 +167,102 @@ export class CoreCoursesCourseLinkHandlerService extends CoreContentLinksHandler
* @param modal Modal, to dismiss when needed.
* @return The course after self enrolling or undefined if the user has access but is not enrolled.
*/
protected checkSelfUserCanSelfEnrolOrAccess(
protected async checkSelfUserCanSelfEnrolOrAccess(
courseId: number,
url: string,
modal: CoreIonLoadingElement,
): Promise<CoreEnrolledCourseData | undefined> {
// User is not enrolled in the course. Check if can self enrol.
return this.canSelfEnrol(courseId).then(async () => {
modal.dismiss();
const isEnrolUrl = !!url.match(/(\/enrol\/index\.php)|(\/course\/enrol\.php)/);
const isEnrolUrl = !!url.match(/(\/enrol\/index\.php)|(\/course\/enrol\.php)/);
if (!isEnrolUrl) {
// Not an enrol URL, check if the user can access the course (e.g. guest access).
const canAccess = await this.canAccess(courseId);
if (canAccess) {
return;
}
}
// The user can self enrol. If it's not a enrolment URL we'll ask for confirmation.
if (!isEnrolUrl) {
try {
await CoreDomUtils.showConfirm(Translate.instant('core.courses.confirmselfenrol'));
} catch {
// User cancelled. Check if the user can view the course contents (guest access or similar).
await CoreCourse.getSections(courseId, false, true);
// User cannot access the course or it's an enrol URL. Check if can self enrol.
const canSelfEnrol = await this.canSelfEnrol(courseId);
if (!canSelfEnrol) {
if (isEnrolUrl) {
// Cannot self enrol, check if the user can access the course (e.g. guest access).
const canAccess = await this.canAccess(courseId);
if (canAccess) {
return;
}
}
// Enrol URL or user confirmed.
try {
return this.selfEnrol(courseId);
} catch (error) {
if (error) {
CoreDomUtils.showErrorModal(error);
}
// Cannot self enrol and cannot access. Show error and allow the user to open the link in browser.
modal.dismiss();
const notEnrolledMessage = Translate.instant('core.courses.notenroled');
const body = CoreTextUtils.buildSeveralParagraphsMessage(
[notEnrolledMessage, Translate.instant('core.confirmopeninbrowser')],
);
throw error;
}
}, async (error) => {
// Can't self enrol. Check if the user can view the course contents (guest access or similar).
try {
await CoreCourse.getSections(courseId, false, true);
await CoreDomUtils.showConfirm(body);
CoreSites.getCurrentSite()?.openInBrowserWithAutoLogin(url, undefined, { showBrowserWarning: false });
} catch {
// Error. Show error message and allow the user to open the link in browser.
modal.dismiss();
// User cancelled.
};
if (error) {
error = CoreTextUtils.getErrorMessageFromError(error) || error;
}
if (!error) {
error = Translate.instant('core.courses.notenroled');
}
throw new CoreError(notEnrolledMessage);
}
const body = CoreTextUtils.buildSeveralParagraphsMessage(
[error, Translate.instant('core.confirmopeninbrowser')],
);
// The user can self enrol. If it's not a enrolment URL we'll ask for confirmation.
modal.dismiss();
try {
await CoreDomUtils.showConfirm(body);
if (!isEnrolUrl) {
await CoreDomUtils.showConfirm(Translate.instant('core.courses.confirmselfenrol'));
}
CoreSites.getCurrentSite()?.openInBrowserWithAutoLogin(url, undefined, { showBrowserWarning: false });
} catch {
// User cancelled.
};
throw error;
try {
return await this.selfEnrol(courseId);
} catch (error) {
if (error) {
CoreDomUtils.showErrorModal(error);
}
return undefined;
});
throw error;
}
}
/**
* Check if user can access the course.
*
* @param courseId Course ID.
* @return Promise resolved with boolean: whether user can access the course.
*/
protected canAccess(courseId: number): Promise<boolean> {
return CoreUtils.promiseWorks(CoreCourse.getSections(courseId, false, true));
}
/**
* Check if a user can be "automatically" self enrolled in a course.
*
* @param courseId Course ID.
* @return Promise resolved if user can be enrolled in a course, rejected otherwise.
* @return Promise resolved with boolean: whether the user can be enrolled in a course.
*/
protected async canSelfEnrol(courseId: number): Promise<void> {
// Check that the course has self enrolment enabled.
protected async canSelfEnrol(courseId: number): Promise<boolean> {
try {
// Check that the course has self enrolment enabled.
const methods = await CoreCourses.getCourseEnrolmentMethods(courseId);
const methods = await CoreCourses.getCourseEnrolmentMethods(courseId);
let isSelfEnrolEnabled = false;
let instances = 0;
methods.forEach((method) => {
if (method.type == 'self' && method.status) {
isSelfEnrolEnabled = true;
instances++;
}
});
let isSelfEnrolEnabled = false;
let instances = 0;
methods.forEach((method) => {
if (method.type == 'self' && method.status) {
isSelfEnrolEnabled = true;
instances++;
}
});
if (!isSelfEnrolEnabled || instances != 1) {
// Self enrol not enabled or more than one instance.
throw new CoreError('Self enrol not enabled in course');
return isSelfEnrolEnabled && instances === 1;
} catch {
return false;
}
}
@ -272,32 +279,29 @@ export class CoreCoursesCourseLinkHandlerService extends CoreContentLinksHandler
try {
await CoreCourses.selfEnrol(courseId, password);
// Success self enrolling the user, invalidate the courses list.
await CoreUtils.ignoreErrors(CoreCourses.invalidateUserCourses());
try {
// Sometimes the list of enrolled courses takes a while to be updated. Wait for it.
return this.waitForEnrolled(courseId, true);
return await this.waitForEnrolled(courseId, true);
} finally {
modal.dismiss();
}
} catch (error) {
modal.dismiss();
if (error && error.code === CoreCoursesProvider.ENROL_INVALID_KEY) {
if (error && error.errorcode === CoreCoursesProvider.ENROL_INVALID_KEY) {
// Invalid password. Allow the user to input password.
const title = Translate.instant('core.courses.selfenrolment');
const body = ' '; // Empty message.
let body = ' '; // Empty message.
const placeholder = Translate.instant('core.courses.password');
if (typeof password != 'undefined') {
// The user attempted a password. Show an error message.
CoreDomUtils.showErrorModal(error);
body = CoreTextUtils.getErrorMessageFromError(error) || body;
}
password = await CoreDomUtils.showPrompt(body, title, placeholder);
return this.selfEnrol(courseId, password);
await this.selfEnrol(courseId, password);
} else {
throw error;
}
@ -319,21 +323,17 @@ export class CoreCoursesCourseLinkHandlerService extends CoreContentLinksHandler
// Check if user is enrolled in the course.
await CoreUtils.ignoreErrors(CoreCourses.invalidateUserCourses());
try {
return CoreCourses.getUserCourse(courseId);
return await CoreCourses.getUserCourse(courseId);
} catch {
// Not enrolled, wait a bit and try again.
if (Date.now() - this.waitStart > 60000) {
// Max time reached, stop.
return;
}
return new Promise((resolve, reject): void => {
setTimeout(() => {
this.waitForEnrolled(courseId)
.then(resolve).catch(reject);
}, 5000);
});
await CoreUtils.wait(5000);
return await this.waitForEnrolled(courseId);
}
}