diff --git a/src/addons/mod/quiz/pages/player/player.ts b/src/addons/mod/quiz/pages/player/player.ts index 4221be887..b2b0a39e9 100644 --- a/src/addons/mod/quiz/pages/player/player.ts +++ b/src/addons/mod/quiz/pages/player/player.ts @@ -884,10 +884,12 @@ export class AddonModQuizPlayerPage implements OnInit, OnDestroy, CanLeave { this.quiz, this.quizAccessInfo, this.preflightData, - attempt, - this.offline, - false, - 'addon.mod_quiz.startattempt', + { + attempt, + offline: this.offline, + finishedOffline: attempt?.finishedOffline, + title: 'addon.mod_quiz.startattempt', + }, ); // Re-fetch attempt access information with the right attempt (might have changed because a new attempt was created). diff --git a/src/addons/mod/quiz/services/handlers/prefetch.ts b/src/addons/mod/quiz/services/handlers/prefetch.ts index 29ad90720..595175af4 100644 --- a/src/addons/mod/quiz/services/handlers/prefetch.ts +++ b/src/addons/mod/quiz/services/handlers/prefetch.ts @@ -167,11 +167,12 @@ export class AddonModQuizPrefetchHandlerService extends CoreCourseActivityPrefet quiz, accessInfo, preflightData, - attempt, - false, - true, - title, - siteId, + { + attempt, + prefetch: true, + title, + siteId, + }, ); } else { // Get some fixed preflight data from access rules (data that doesn't require user interaction). diff --git a/src/addons/mod/quiz/services/quiz-helper.ts b/src/addons/mod/quiz/services/quiz-helper.ts index 9f2fd4cb9..209e190c7 100644 --- a/src/addons/mod/quiz/services/quiz-helper.ts +++ b/src/addons/mod/quiz/services/quiz-helper.ts @@ -128,24 +128,14 @@ export class AddonModQuizHelperProvider { * @param quiz Quiz. * @param accessInfo Quiz access info. * @param preflightData Object where to store the preflight data. - * @param attempt Attempt to continue. Don't pass any value if the user needs to start a new attempt. - * @param offline Whether the attempt is offline. - * @param prefetch Whether user is prefetching. - * @param title The title to display in the modal and in the submit button. - * @param siteId Site ID. If not defined, current site. - * @param retrying Whether we're retrying after a failure. + * @param options Options. * @returns Promise resolved when the preflight data is validated. The resolve param is the attempt. */ async getAndCheckPreflightData( quiz: AddonModQuizQuizWSData, accessInfo: AddonModQuizGetQuizAccessInformationWSResponse, preflightData: Record, - attempt?: AddonModQuizAttemptWSData, - offline?: boolean, - prefetch?: boolean, - title?: string, - siteId?: string, - retrying?: boolean, + options: GetAndCheckPreflightOptions = {}, ): Promise { const rules = accessInfo?.activerulenames; @@ -154,30 +144,37 @@ export class AddonModQuizHelperProvider { const preflightCheckRequired = await AddonModQuizAccessRuleDelegate.isPreflightCheckRequired( rules, quiz, - attempt, - prefetch, - siteId, + options.attempt, + options.prefetch, + options.siteId, ); if (preflightCheckRequired) { // Preflight check is required. Show a modal with the preflight form. - const data = await this.getPreflightData(quiz, accessInfo, attempt, prefetch, title, siteId); + const data = await this.getPreflightData(quiz, accessInfo, options); // Data entered by the user, add it to preflight data and check it again. Object.assign(preflightData, data); } // Get some fixed preflight data from access rules (data that doesn't require user interaction). - await AddonModQuizAccessRuleDelegate.getFixedPreflightData(rules, quiz, preflightData, attempt, prefetch, siteId); + await AddonModQuizAccessRuleDelegate.getFixedPreflightData( + rules, + quiz, + preflightData, + options.attempt, + options.prefetch, + options.siteId, + ); try { // All the preflight data is gathered, now validate it. - return await this.validatePreflightData(quiz, accessInfo, preflightData, attempt, offline, prefetch, siteId); + return await this.validatePreflightData(quiz, accessInfo, preflightData, options); } catch (error) { - if (prefetch) { + if (options.prefetch) { throw error; - } else if (retrying && !preflightCheckRequired) { + } else if (options.retrying && !preflightCheckRequired) { // We're retrying after a failure, but the preflight check wasn't required. // This means there's something wrong with some access rule or user is offline and data isn't cached. // Don't retry again because it would lead to an infinite loop. @@ -190,17 +187,10 @@ export class AddonModQuizHelperProvider { CoreDomUtils.showErrorModalDefault(error, 'core.error', true); }, 100); - return this.getAndCheckPreflightData( - quiz, - accessInfo, - preflightData, - attempt, - offline, - prefetch, - title, - siteId, - true, - ); + return this.getAndCheckPreflightData(quiz, accessInfo, preflightData, { + ...options, + retrying: true, + }); } } @@ -209,19 +199,13 @@ export class AddonModQuizHelperProvider { * * @param quiz Quiz. * @param accessInfo Quiz access info. - * @param attempt The attempt started/continued. If not supplied, user is starting a new attempt. - * @param prefetch Whether the user is prefetching the quiz. - * @param title The title to display in the modal and in the submit button. - * @param siteId Site ID. If not defined, current site. + * @param options Options. * @returns Promise resolved with the preflight data. Rejected if user cancels. */ async getPreflightData( quiz: AddonModQuizQuizWSData, accessInfo: AddonModQuizGetQuizAccessInformationWSResponse, - attempt?: AddonModQuizAttemptWSData, - prefetch?: boolean, - title?: string, - siteId?: string, + options: GetPreflightOptions = {}, ): Promise> { const notSupported: string[] = []; const rules = accessInfo?.activerulenames; @@ -243,11 +227,11 @@ export class AddonModQuizHelperProvider { const modalData = await CoreDomUtils.openModal>({ component: AddonModQuizPreflightModalComponent, componentProps: { - title: title, + title: options.title, quiz, - attempt, - prefetch: !!prefetch, - siteId: siteId, + attempt: options.attempt, + prefetch: !!options.prefetch, + siteId: options.siteId, rules: rules, }, }); @@ -412,36 +396,32 @@ export class AddonModQuizHelperProvider { * @param quiz Quiz. * @param accessInfo Quiz access info. * @param preflightData Object where to store the preflight data. - * @param attempt Attempt to continue. Don't pass any value if the user needs to start a new attempt. - * @param offline Whether the attempt is offline. - * @param prefetch Whether user is prefetching. - * @param siteId Site ID. If not defined, current site. + * @param options Options * @returns Promise resolved when the preflight data is validated. */ async validatePreflightData( quiz: AddonModQuizQuizWSData, accessInfo: AddonModQuizGetQuizAccessInformationWSResponse, preflightData: Record, - attempt?: AddonModQuizAttempt, - offline?: boolean, - prefetch?: boolean, - siteId?: string, + options: ValidatePreflightOptions = {}, ): Promise { const rules = accessInfo.activerulenames; const modOptions = { cmId: quiz.coursemodule, - readingStrategy: offline ? CoreSitesReadingStrategy.PREFER_CACHE : CoreSitesReadingStrategy.ONLY_NETWORK, - siteId, + readingStrategy: options.offline ? CoreSitesReadingStrategy.PREFER_CACHE : CoreSitesReadingStrategy.ONLY_NETWORK, + siteId: options.siteId, }; + let attempt = options.attempt; try { + if (attempt) { - if (attempt.state !== AddonModQuizAttemptStates.OVERDUE && !attempt.finishedOffline) { + if (attempt.state !== AddonModQuizAttemptStates.OVERDUE && !options.finishedOffline) { // We're continuing an attempt. Call getAttemptData to validate the preflight data. await AddonModQuiz.getAttemptData(attempt.id, attempt.currentpage ?? 0, preflightData, modOptions); - if (offline) { + if (options.offline) { // Get current page stored in local. const storedAttempt = await CoreUtils.ignoreErrors( AddonModQuizOffline.getAttemptById(attempt.id), @@ -456,7 +436,7 @@ export class AddonModQuizHelperProvider { } } else { // We're starting a new attempt, call startAttempt. - attempt = await AddonModQuiz.startAttempt(quiz.id, preflightData, false, siteId); + attempt = await AddonModQuiz.startAttempt(quiz.id, preflightData, false, options.siteId); } // Preflight data validated. @@ -465,8 +445,8 @@ export class AddonModQuizHelperProvider { quiz, attempt, preflightData, - prefetch, - siteId, + options.prefetch, + options.siteId, ); return attempt; @@ -478,8 +458,8 @@ export class AddonModQuizHelperProvider { quiz, attempt, preflightData, - prefetch, - siteId, + options.prefetch, + options.siteId, ); } @@ -512,3 +492,27 @@ export type AddonModQuizAttempt = AddonModQuizAttemptWSData & { completed?: boolean; formattedGrade?: string; }; + +/** + * Options to validate preflight data. + */ +type ValidatePreflightOptions = { + attempt?: AddonModQuizAttemptWSData; // Attempt to continue. Don't pass any value if the user needs to start a new attempt. + offline?: boolean; // Whether the attempt is offline. + finishedOffline?: boolean; // Whether the attempt is finished offline. + prefetch?: boolean; // Whether user is prefetching. + siteId?: string; // Site ID. If not defined, current site. +}; + +/** + * Options to check preflight data. + */ +type GetAndCheckPreflightOptions = ValidatePreflightOptions & { + title?: string; // The title to display in the modal and in the submit button. + retrying?: boolean; // Whether we're retrying after a failure. +}; + +/** + * Options to get preflight data. + */ +type GetPreflightOptions = Omit;