MOBILE-2348 core: Return a 'canceled' error in showConfirm

main
Dani Palou 2018-04-06 08:58:23 +02:00
parent ad1e564600
commit 01848965d8
15 changed files with 107 additions and 103 deletions

View File

@ -518,18 +518,18 @@ export class AddonMessagesDiscussionPage implements OnDestroy {
this.domUtils.showConfirm(this.translate.instant(langKey)).then(() => { this.domUtils.showConfirm(this.translate.instant(langKey)).then(() => {
const modal = this.domUtils.showModalLoading('core.deleting', true); const modal = this.domUtils.showModalLoading('core.deleting', true);
this.messagesProvider.deleteMessage(message).then(() => { return this.messagesProvider.deleteMessage(message).then(() => {
// Remove message from the list without having to wait for re-fetch. // Remove message from the list without having to wait for re-fetch.
this.messages.splice(index, 1); this.messages.splice(index, 1);
this.removeMessage(message.hash); this.removeMessage(message.hash);
this.notifyNewMessage(); this.notifyNewMessage();
this.fetchData(); // Re-fetch messages to update cached data. this.fetchData(); // Re-fetch messages to update cached data.
}).catch((error) => {
this.domUtils.showErrorModalDefault(error, 'addon.messages.errordeletemessage', true);
}).finally(() => { }).finally(() => {
modal.dismiss(); modal.dismiss();
}); });
}).catch((error) => {
this.domUtils.showErrorModalDefault(error, 'addon.messages.errordeletemessage', true);
}); });
} }

View File

@ -100,8 +100,6 @@ export class AddonMessagesAddContactUserHandler implements CoreUserProfileHandle
return this.domUtils.showConfirm(template, title, title).then(() => { return this.domUtils.showConfirm(template, title, title).then(() => {
return this.messagesProvider.removeContact(user.id); return this.messagesProvider.removeContact(user.id);
}, () => {
// Ignore on cancel.
}); });
} else { } else {
return this.messagesProvider.addContact(user.id); return this.messagesProvider.addContact(user.id);

View File

@ -103,8 +103,6 @@ export class AddonMessagesBlockContactUserHandler implements CoreUserProfileHand
return this.domUtils.showConfirm(template, title, title).then(() => { return this.domUtils.showConfirm(template, title, title).then(() => {
return this.messagesProvider.blockContact(user.id); return this.messagesProvider.blockContact(user.id);
}, () => {
// Ignore on cancel.
}); });
} }
}).catch((error) => { }).catch((error) => {

View File

@ -172,7 +172,7 @@ export class AddonModQuizPlayerPage implements OnInit, OnDestroy {
answers[button.name] = button.value; answers[button.name] = button.value;
// Behaviour checks are always in online. // Behaviour checks are always in online.
this.quizProvider.processAttempt(this.quiz, this.attempt, answers, this.preflightData).then(() => { return this.quizProvider.processAttempt(this.quiz, this.attempt, answers, this.preflightData).then(() => {
// Reload the current page. // Reload the current page.
const scrollElement = this.content.getScrollElement(), const scrollElement = this.content.getScrollElement(),
scrollTop = scrollElement.scrollTop || 0, scrollTop = scrollElement.scrollTop || 0,
@ -185,11 +185,11 @@ export class AddonModQuizPlayerPage implements OnInit, OnDestroy {
this.loaded = true; this.loaded = true;
this.content.scrollTo(scrollLeft, scrollTop); this.content.scrollTo(scrollLeft, scrollTop);
}); });
}).catch((error) => {
this.domUtils.showErrorModalDefault(error, 'Error performing action.');
}).finally(() => { }).finally(() => {
modal.dismiss(); modal.dismiss();
}); });
}).catch((error) => {
this.domUtils.showErrorModalDefault(error, 'Error performing action.');
}); });
} }
@ -354,11 +354,11 @@ export class AddonModQuizPlayerPage implements OnInit, OnDestroy {
// Leave the player. // Leave the player.
this.forceLeave = true; this.forceLeave = true;
this.navCtrl.pop(); this.navCtrl.pop();
}).catch((error) => {
this.domUtils.showErrorModalDefault(error, 'addon.mod_quiz.errorsaveattempt', true);
}).finally(() => { }).finally(() => {
modal.dismiss(); modal.dismiss();
}); });
}).catch((error) => {
this.domUtils.showErrorModalDefault(error, 'addon.mod_quiz.errorsaveattempt', true);
}); });
} }
@ -560,13 +560,9 @@ export class AddonModQuizPlayerPage implements OnInit, OnDestroy {
// Attempt is overdue or finished in offline, we can only load the summary. // Attempt is overdue or finished in offline, we can only load the summary.
return this.loadSummary(); return this.loadSummary();
} }
}).catch((error) => {
this.domUtils.showErrorModalDefault(error, 'addon.mod_quiz.errorgetquestions', true);
}); });
}).catch((error) => { }).catch((error) => {
if (error) { this.domUtils.showErrorModalDefault(error, 'addon.mod_quiz.errorgetquestions', true);
this.domUtils.showErrorModal(error);
}
}); });
} }

View File

@ -139,7 +139,7 @@ export class AddonModQuizHelperProvider {
if (typeof data != 'undefined') { if (typeof data != 'undefined') {
resolve(data); resolve(data);
} else { } else {
reject(null); reject(this.domUtils.createCanceledError());
} }
}); });
}); });

View File

@ -188,15 +188,15 @@ export class AddonModSurveyIndexComponent extends CoreCourseModuleMainActivityCo
}); });
} }
this.surveyProvider.submitAnswers(this.survey.id, this.survey.name, this.courseId, answers).then(() => { return this.surveyProvider.submitAnswers(this.survey.id, this.survey.name, this.courseId, answers).then(() => {
this.content.scrollToTop(); this.content.scrollToTop();
return this.refreshContent(false); return this.refreshContent(false);
}).catch((message) => {
this.domUtils.showErrorModalDefault(message, 'addon.mod_survey.cannotsubmitsurvey', true);
}).finally(() => { }).finally(() => {
modal.dismiss(); modal.dismiss();
}); });
}).catch((message) => {
this.domUtils.showErrorModalDefault(message, 'addon.mod_survey.cannotsubmitsurvey', true);
}); });
} }

View File

@ -158,14 +158,17 @@ export class CoreFileComponent implements OnInit, OnDestroy {
promise = this.fileSize ? this.domUtils.confirmDownloadSize({ size: this.fileSize, total: true }) : Promise.resolve(); promise = this.fileSize ? this.domUtils.confirmDownloadSize({ size: this.fileSize, total: true }) : Promise.resolve();
promise.then(() => { promise.then(() => {
// User confirmed, add the file to queue. // User confirmed, add the file to queue.
this.filepoolProvider.invalidateFileByUrl(this.siteId, this.fileUrl).finally(() => { return this.filepoolProvider.invalidateFileByUrl(this.siteId, this.fileUrl).finally(() => {
this.isDownloading = true; this.isDownloading = true;
this.filepoolProvider.addToQueueByUrl(this.siteId, this.fileUrl, this.component, this.filepoolProvider.addToQueueByUrl(this.siteId, this.fileUrl, this.component,
this.componentId, this.timemodified, undefined, undefined, 0, this.file).catch((error) => { this.componentId, this.timemodified, undefined, undefined, 0, this.file).catch((error) => {
this.domUtils.showErrorModalDefault(error, 'core.errordownloading', true); this.domUtils.showErrorModalDefault(error, 'core.errordownloading', true);
this.calculateState(); this.calculateState();
}); });
}); });
}).catch(() => {
// Ignore error.
}); });
} }
} }

View File

@ -171,15 +171,14 @@ export class CoreLocalFileComponent implements OnInit {
// Ask confirmation. // Ask confirmation.
this.domUtils.showConfirm(this.translate.instant('core.confirmdeletefile')).then(() => { this.domUtils.showConfirm(this.translate.instant('core.confirmdeletefile')).then(() => {
const modal = this.domUtils.showModalLoading(); const modal = this.domUtils.showModalLoading();
this.fileProvider.removeFile(this.relativePath).then(() => {
return this.fileProvider.removeFile(this.relativePath).then(() => {
this.onDelete.emit(); this.onDelete.emit();
}).catch(() => {
this.domUtils.showErrorModal('core.errordeletefile', true);
}).finally(() => { }).finally(() => {
modal.dismiss(); modal.dismiss();
}); });
}).catch(() => { }).catch(() => {
// User cancelled. this.domUtils.showErrorModal('core.errordeletefile', true);
}); });
} }
} }

View File

@ -233,6 +233,8 @@ export class CoreContentLinksHelperProvider {
} else { } else {
this.goToChooseSite(url); this.goToChooseSite(url);
} }
}).catch(() => {
// User canceled.
}); });
} }

View File

@ -283,18 +283,18 @@ export class CoreCourseSectionPage implements OnDestroy {
*/ */
prefetchCourse(): void { prefetchCourse(): void {
this.courseHelper.confirmAndPrefetchCourse(this.prefetchCourseData, this.course, this.sections, this.courseHandlers) this.courseHelper.confirmAndPrefetchCourse(this.prefetchCourseData, this.course, this.sections, this.courseHandlers)
.then((downloaded) => { .then(() => {
if (downloaded && this.downloadEnabled) { if (this.downloadEnabled) {
// Recalculate the status. // Recalculate the status.
this.courseHelper.calculateSectionsStatus(this.sections, this.course.id).catch(() => { this.courseHelper.calculateSectionsStatus(this.sections, this.course.id).catch(() => {
// Ignore errors (shouldn't happen). // Ignore errors (shouldn't happen).
}); });
} }
}).catch((error) => { }).catch((error) => {
if (!this.isDestroyed) { if (!this.isDestroyed) {
this.domUtils.showErrorModalDefault(error, 'core.course.errordownloadingcourse', true); this.domUtils.showErrorModalDefault(error, 'core.course.errordownloadingcourse', true);
} }
}); });
} }
/** /**

View File

@ -249,8 +249,7 @@ export class CoreCourseHelperProvider {
* @param {any} course Course to prefetch. * @param {any} course Course to prefetch.
* @param {any[]} [sections] List of course sections. * @param {any[]} [sections] List of course sections.
* @param {CoreCourseOptionsHandlerToDisplay[]} courseHandlers List of course handlers. * @param {CoreCourseOptionsHandlerToDisplay[]} courseHandlers List of course handlers.
* @return {Promise<boolean>} Promise resolved with true when the download finishes, resolved with false if user doesn't * @return {Promise<boolean>} Promise resolved when the download finishes, rejected if an error occurs or the user cancels.
* confirm, rejected if an error occurs.
*/ */
confirmAndPrefetchCourse(iconData: any, course: any, sections?: any[], courseHandlers?: CoreCourseOptionsHandlerToDisplay[]) confirmAndPrefetchCourse(iconData: any, course: any, sections?: any[], courseHandlers?: CoreCourseOptionsHandlerToDisplay[])
: Promise<boolean> { : Promise<boolean> {
@ -288,11 +287,8 @@ export class CoreCourseHelperProvider {
}, (error): any => { }, (error): any => {
// User cancelled or there was an error calculating the size. // User cancelled or there was an error calculating the size.
iconData.prefetchCourseIcon = initialIcon; iconData.prefetchCourseIcon = initialIcon;
if (error) {
return Promise.reject(error);
}
return false; return Promise.reject(error);
}); });
}); });
} }
@ -302,9 +298,9 @@ export class CoreCourseHelperProvider {
* *
* @param {any[]} courses List of courses to download. * @param {any[]} courses List of courses to download.
* @param {Function} [onProgress] Function to call everytime a course is downloaded. * @param {Function} [onProgress] Function to call everytime a course is downloaded.
* @return {Promise<boolean>} Resolved with true when downloaded, resolved with false if user cancels, rejected if error. * @return {Promise<boolean>} Resolved when downloaded, rejected if error or canceled.
*/ */
confirmAndPrefetchCourses(courses: any[], onProgress?: (data: CoreCourseCoursesProgress) => void): Promise<boolean> { confirmAndPrefetchCourses(courses: any[], onProgress?: (data: CoreCourseCoursesProgress) => void): Promise<any> {
const siteId = this.sitesProvider.getCurrentSiteId(); const siteId = this.sitesProvider.getCurrentSiteId();
// Confirm the download without checking size because it could take a while. // Confirm the download without checking size because it could take a while.
@ -347,12 +343,7 @@ export class CoreCourseHelperProvider {
onProgress({ count: 0, total: total, success: true }); onProgress({ count: 0, total: total, success: true });
} }
return this.utils.allPromises(promises).then(() => { return this.utils.allPromises(promises);
return true;
});
}, () => {
// User cancelled.
return false;
}); });
} }
@ -426,23 +417,18 @@ export class CoreCourseHelperProvider {
*/ */
contextMenuPrefetch(instance: any, module: any, courseId: number): Promise<any> { contextMenuPrefetch(instance: any, module: any, courseId: number): Promise<any> {
const initialIcon = instance.prefetchStatusIcon; const initialIcon = instance.prefetchStatusIcon;
let cancelled = false;
instance.prefetchStatusIcon = 'spinner'; // Show spinner since this operation might take a while. instance.prefetchStatusIcon = 'spinner'; // Show spinner since this operation might take a while.
// We need to call getDownloadSize, the package might have been updated. // We need to call getDownloadSize, the package might have been updated.
return this.prefetchDelegate.getModuleDownloadSize(module, courseId, true).then((size) => { return this.prefetchDelegate.getModuleDownloadSize(module, courseId, true).then((size) => {
return this.domUtils.confirmDownloadSize(size).catch(() => { return this.domUtils.confirmDownloadSize(size).then(() => {
// User hasn't confirmed, stop.
cancelled = true;
return Promise.reject(null);
}).then(() => {
return this.prefetchDelegate.prefetchModule(module, courseId, true); return this.prefetchDelegate.prefetchModule(module, courseId, true);
}); });
}).catch((error) => { }).catch((error) => {
instance.prefetchStatusIcon = initialIcon; instance.prefetchStatusIcon = initialIcon;
if (!instance.isDestroyed && !cancelled) {
if (!instance.isDestroyed) {
this.domUtils.showErrorModalDefault(error, 'core.errordownloading', true); this.domUtils.showErrorModalDefault(error, 'core.errordownloading', true);
} }
}); });
@ -979,36 +965,37 @@ export class CoreCourseHelperProvider {
// First of all, mark the course as being downloaded. // First of all, mark the course as being downloaded.
this.courseDwnPromises[siteId][course.id] = this.courseProvider.setCourseStatus(course.id, CoreConstants.DOWNLOADING, this.courseDwnPromises[siteId][course.id] = this.courseProvider.setCourseStatus(course.id, CoreConstants.DOWNLOADING,
siteId).then(() => { siteId).then(() => {
const promises = [];
let allSectionsSection = sections[0];
// Prefetch all the sections. If the first section is "All sections", use it. Otherwise, use a fake "All sections". const promises = [];
if (sections[0].id != CoreCourseProvider.ALL_SECTIONS_ID) { let allSectionsSection = sections[0];
allSectionsSection = { id: CoreCourseProvider.ALL_SECTIONS_ID };
// Prefetch all the sections. If the first section is "All sections", use it. Otherwise, use a fake "All sections".
if (sections[0].id != CoreCourseProvider.ALL_SECTIONS_ID) {
allSectionsSection = { id: CoreCourseProvider.ALL_SECTIONS_ID };
}
promises.push(this.prefetchSection(allSectionsSection, course.id, sections));
// Prefetch course options.
courseHandlers.forEach((handler) => {
if (handler.prefetch) {
promises.push(handler.prefetch(course));
} }
promises.push(this.prefetchSection(allSectionsSection, course.id, sections));
// Prefetch course options.
courseHandlers.forEach((handler) => {
if (handler.prefetch) {
promises.push(handler.prefetch(course));
}
});
return this.utils.allPromises(promises);
}).then(() => {
// Download success, mark the course as downloaded.
return this.courseProvider.setCourseStatus(course.id, CoreConstants.DOWNLOADED, siteId);
}).catch((error) => {
// Error, restore previous status.
return this.courseProvider.setCoursePreviousStatus(course.id, siteId).then(() => {
return Promise.reject(error);
});
}).finally(() => {
delete this.courseDwnPromises[siteId][course.id];
}); });
return this.utils.allPromises(promises);
}).then(() => {
// Download success, mark the course as downloaded.
return this.courseProvider.setCourseStatus(course.id, CoreConstants.DOWNLOADED, siteId);
}).catch((error) => {
// Error, restore previous status.
return this.courseProvider.setCoursePreviousStatus(course.id, siteId).then(() => {
return Promise.reject(error);
});
}).finally(() => {
delete this.courseDwnPromises[siteId][course.id];
});
return this.courseDwnPromises[siteId][course.id]; return this.courseDwnPromises[siteId][course.id];
} }

View File

@ -160,9 +160,9 @@ export class CoreCoursesMyCoursesPage implements OnDestroy {
return this.courseHelper.confirmAndPrefetchCourses(this.courses, (progress) => { return this.courseHelper.confirmAndPrefetchCourses(this.courses, (progress) => {
this.prefetchCoursesData.badge = progress.count + ' / ' + progress.total; this.prefetchCoursesData.badge = progress.count + ' / ' + progress.total;
}).then((downloaded) => { }).then(() => {
this.prefetchCoursesData.icon = downloaded ? 'ion-android-refresh' : initialIcon; this.prefetchCoursesData.icon = 'ion-android-refresh';
}, (error) => { }).catch((error) => {
if (!this.isDestroyed) { if (!this.isDestroyed) {
this.domUtils.showErrorModalDefault(error, 'core.course.errordownloadingcourse', true); this.domUtils.showErrorModalDefault(error, 'core.course.errordownloadingcourse', true);
this.prefetchCoursesData.icon = initialIcon; this.prefetchCoursesData.icon = initialIcon;

View File

@ -362,9 +362,9 @@ export class CoreCoursesMyOverviewPage implements OnDestroy {
return this.courseHelper.confirmAndPrefetchCourses(this.courses[selected], (progress) => { return this.courseHelper.confirmAndPrefetchCourses(this.courses[selected], (progress) => {
selectedData.badge = progress.count + ' / ' + progress.total; selectedData.badge = progress.count + ' / ' + progress.total;
}).then((downloaded) => { }).then(() => {
selectedData.icon = downloaded ? 'refresh' : initialIcon; selectedData.icon = 'refresh';
}, (error) => { }).catch((error) => {
if (!this.isDestroyed) { if (!this.isDestroyed) {
this.domUtils.showErrorModalDefault(error, 'core.course.errordownloadingcourse', true); this.domUtils.showErrorModalDefault(error, 'core.course.errordownloadingcourse', true);
selectedData.icon = initialIcon; selectedData.icon = initialIcon;

View File

@ -235,7 +235,7 @@ export class CoreLoginHelperProvider {
promise.then(() => { promise.then(() => {
this.openBrowserForSSOLogin(siteUrl, typeOfLogin, service, launchUrl); this.openBrowserForSSOLogin(siteUrl, typeOfLogin, service, launchUrl);
}, () => { }).catch(() => {
// User cancelled, ignore. // User cancelled, ignore.
}); });
} }

View File

@ -139,6 +139,15 @@ export class CoreDomUtilsProvider {
return Promise.resolve(); return Promise.resolve();
} }
/**
* Create a "cancelled" error. These errors won't display an error message in showErrorModal functions.
*
* @return {any} The error object.
*/
createCanceledError(): any {
return {coreCanceled: true};
}
/** /**
* Extract the downloadable URLs from an HTML code. * Extract the downloadable URLs from an HTML code.
* *
@ -771,7 +780,7 @@ export class CoreDomUtilsProvider {
* @param {string} [okText] Text of the OK button. * @param {string} [okText] Text of the OK button.
* @param {string} [cancelText] Text of the Cancel button. * @param {string} [cancelText] Text of the Cancel button.
* @param {any} [options] More options. See https://ionicframework.com/docs/api/components/alert/AlertController/ * @param {any} [options] More options. See https://ionicframework.com/docs/api/components/alert/AlertController/
* @return {Promise<void>} Promise resolved if the user confirms and rejected if he cancels. * @return {Promise<void>} Promise resolved if the user confirms and rejected with a canceled error if he cancels.
*/ */
showConfirm(message: string, title?: string, okText?: string, cancelText?: string, options?: any): Promise<void> { showConfirm(message: string, title?: string, okText?: string, cancelText?: string, options?: any): Promise<void> {
return new Promise<void>((resolve, reject): void => { return new Promise<void>((resolve, reject): void => {
@ -787,7 +796,7 @@ export class CoreDomUtilsProvider {
text: cancelText || this.translate.instant('core.cancel'), text: cancelText || this.translate.instant('core.cancel'),
role: 'cancel', role: 'cancel',
handler: (): void => { handler: (): void => {
reject(); reject(this.createCanceledError());
} }
}, },
{ {
@ -813,7 +822,10 @@ export class CoreDomUtilsProvider {
showErrorModal(error: any, needsTranslate?: boolean, autocloseTime?: number): Alert { showErrorModal(error: any, needsTranslate?: boolean, autocloseTime?: number): Alert {
if (typeof error == 'object') { if (typeof error == 'object') {
// We received an object instead of a string. Search for common properties. // We received an object instead of a string. Search for common properties.
if (typeof error.content != 'undefined') { if (error.coreCanceled) {
// It's a canceled error, don't display an error.
return;
} else if (typeof error.content != 'undefined') {
error = error.content; error = error.content;
} else if (typeof error.body != 'undefined') { } else if (typeof error.body != 'undefined') {
error = error.body; error = error.body;
@ -833,6 +845,11 @@ export class CoreDomUtilsProvider {
} }
} }
if (error == CoreConstants.DONT_SHOW_ERROR) {
// The error shouldn't be shown, stop.
return;
}
const message = this.textUtils.decodeHTML(needsTranslate ? this.translate.instant(error) : error); const message = this.textUtils.decodeHTML(needsTranslate ? this.translate.instant(error) : error);
return this.showAlert(this.getErrorTitle(message), message, undefined, autocloseTime); return this.showAlert(this.getErrorTitle(message), message, undefined, autocloseTime);
@ -848,14 +865,18 @@ export class CoreDomUtilsProvider {
* @return {Alert} The alert modal. * @return {Alert} The alert modal.
*/ */
showErrorModalDefault(error: any, defaultError: any, needsTranslate?: boolean, autocloseTime?: number): Alert { showErrorModalDefault(error: any, defaultError: any, needsTranslate?: boolean, autocloseTime?: number): Alert {
if (error != CoreConstants.DONT_SHOW_ERROR) { if (error && error.coreCanceled) {
if (error && typeof error != 'string') { // It's a canceled error, don't display an error.
error = error.message || error.error; return;
}
error = typeof error == 'string' ? error : defaultError;
return this.showErrorModal(error, needsTranslate, autocloseTime);
} }
if (error && typeof error != 'string') {
error = error.message || error.error || error.content || error.body;
}
error = typeof error == 'string' ? error : defaultError;
return this.showErrorModal(error, needsTranslate, autocloseTime);
} }
/** /**