From 344ee6d57ecc65b7a521639512e3da8ffa1f7195 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Mon, 14 Feb 2022 17:07:46 +0100 Subject: [PATCH] MOBILE-3931 module: Remove unnecessary variables and menus from modules --- scripts/langindex.json | 1 - .../index/addon-mod-assign-index.html | 25 ---- .../mod/assign/components/index/index.ts | 136 +++++++----------- .../components/index/index.html | 18 --- .../bigbluebuttonbn/components/index/index.ts | 19 ++- .../index/addon-mod-book-index.html | 16 --- src/addons/mod/book/components/index/index.ts | 14 +- .../index/addon-mod-chat-index.html | 22 --- src/addons/mod/chat/components/index/index.ts | 32 ++--- .../index/addon-mod-choice-index.html | 24 ---- .../mod/choice/components/index/index.ts | 60 ++++---- .../index/addon-mod-data-index.html | 22 --- src/addons/mod/data/components/index/index.ts | 10 +- .../index/addon-mod-feedback-index.html | 24 ---- .../mod/feedback/components/index/index.ts | 5 +- .../index/addon-mod-folder-index.html | 21 --- .../mod/folder/components/index/index.ts | 22 +-- .../mod/forum/components/index/index.html | 23 --- .../mod/forum/components/index/index.ts | 10 +- src/addons/mod/forum/lang.json | 1 - .../index/addon-mod-glossary-index.html | 22 --- .../mod/glossary/components/index/index.ts | 54 ++++--- .../index/addon-mod-h5pactivity-index.html | 25 +--- .../mod/h5pactivity/components/index/index.ts | 81 +++++------ .../index/addon-mod-imscp-index.html | 20 --- .../mod/imscp/components/index/index.ts | 50 +++---- .../index/addon-mod-lesson-index.html | 24 ---- .../mod/lesson/components/index/index.ts | 115 +++++++-------- .../components/index/addon-mod-lti-index.html | 17 +-- src/addons/mod/lti/components/index/index.ts | 15 +- .../index/addon-mod-page-index.html | 21 --- src/addons/mod/page/components/index/index.ts | 29 ++-- .../index/addon-mod-quiz-index.html | 26 +--- src/addons/mod/quiz/components/index/index.ts | 135 ++++++++--------- .../index/addon-mod-resource-index.html | 21 +-- .../mod/resource/components/index/index.ts | 114 ++++++++------- .../index/addon-mod-scorm-index.html | 26 +--- .../mod/scorm/components/index/index.ts | 50 +++---- .../index/addon-mod-survey-index.html | 27 +--- .../mod/survey/components/index/index.ts | 45 +++--- .../components/index/addon-mod-url-index.html | 11 -- .../index/addon-mod-wiki-index.html | 22 --- src/addons/mod/wiki/components/index/index.ts | 23 ++- .../index/addon-mod-workshop-index.html | 25 ---- .../mod/workshop/components/index/index.ts | 82 +++++------ .../course/classes/main-activity-component.ts | 53 +------ .../course/classes/main-resource-component.ts | 125 ++++++---------- .../features/course/services/course-helper.ts | 2 + 48 files changed, 534 insertions(+), 1231 deletions(-) diff --git a/scripts/langindex.json b/scripts/langindex.json index 3bdd8c444..07000f48f 100644 --- a/scripts/langindex.json +++ b/scripts/langindex.json @@ -649,7 +649,6 @@ "addon.mod_forum.posttomygroups": "forum", "addon.mod_forum.privatereply": "forum", "addon.mod_forum.re": "forum", - "addon.mod_forum.refreshdiscussions": "local_moodlemobileapp", "addon.mod_forum.refreshposts": "local_moodlemobileapp", "addon.mod_forum.removefromfavourites": "forum", "addon.mod_forum.reply": "forum", diff --git a/src/addons/mod/assign/components/index/addon-mod-assign-index.html b/src/addons/mod/assign/components/index/addon-mod-assign-index.html index 73d0903e9..69b0d2d25 100644 --- a/src/addons/mod/assign/components/index/addon-mod-assign-index.html +++ b/src/addons/mod/assign/components/index/addon-mod-assign-index.html @@ -1,30 +1,5 @@ - - - - - - - - - - - - - - - - - diff --git a/src/addons/mod/assign/components/index/index.ts b/src/addons/mod/assign/components/index/index.ts index 28827e331..c78728728 100644 --- a/src/addons/mod/assign/components/index/index.ts +++ b/src/addons/mod/assign/components/index/index.ts @@ -23,7 +23,6 @@ import { CoreGroupInfo, CoreGroups } from '@services/groups'; import { CoreNavigator } from '@services/navigator'; import { CoreSites } from '@services/sites'; import { CoreDomUtils } from '@services/utils/dom'; -import { CoreTextUtils } from '@services/utils/text'; import { CoreTimeUtils } from '@services/utils/time'; import { CoreUtils } from '@services/utils/utils'; import { Translate } from '@singletons'; @@ -161,104 +160,75 @@ export class AddonModAssignIndexComponent extends CoreCourseModuleMainActivityCo } /** - * Expand the description. + * @inheritdoc */ - expandDescription(ev?: Event): void { - ev?.preventDefault(); - ev?.stopPropagation(); - - if (this.assign && (this.description || this.assign.introattachments)) { - CoreTextUtils.viewText(Translate.instant('core.description'), this.description || '', { - component: this.component, - componentId: this.module.id, - files: this.assign.introattachments, - filter: true, - contextLevel: 'module', - instanceId: this.module.id, - courseId: this.courseId, - }); - } - } - - /** - * Get assignment data. - * - * @param refresh If it's refreshing content. - * @param sync If it should try to sync. - * @param showErrors If show errors to the user of hide them. - * @return Promise resolved when done. - */ - protected async fetchContent(refresh = false, sync = false, showErrors = false): Promise { + protected async fetchContent(refresh?: boolean, sync = false, showErrors = false): Promise { // Get assignment data. - try { - this.assign = await AddonModAssign.getAssignment(this.courseId, this.module.id); + this.assign = await AddonModAssign.getAssignment(this.courseId, this.module.id); - this.dataRetrieved.emit(this.assign); - this.description = this.assign.intro; + this.dataRetrieved.emit(this.assign); + this.description = this.assign.intro; - if (sync) { - // Try to synchronize the assign. - await CoreUtils.ignoreErrors(this.syncActivity(showErrors)); - } + if (sync) { + // Try to synchronize the assign. + await CoreUtils.ignoreErrors(this.syncActivity(showErrors)); + } - // Check if there's any offline data for this assign. - this.hasOffline = await AddonModAssignOffline.hasAssignOfflineData(this.assign.id); + // Check if there's any offline data for this assign. + this.hasOffline = await AddonModAssignOffline.hasAssignOfflineData(this.assign.id); - // Get assignment submissions. - const submissions = await AddonModAssign.getSubmissions(this.assign.id, { cmId: this.module.id }); - const time = CoreTimeUtils.timestamp(); + // Get assignment submissions. + const submissions = await AddonModAssign.getSubmissions(this.assign.id, { cmId: this.module.id }); + const time = CoreTimeUtils.timestamp(); - this.canViewAllSubmissions = submissions.canviewsubmissions; + this.canViewAllSubmissions = submissions.canviewsubmissions; - if (submissions.canviewsubmissions) { + if (submissions.canviewsubmissions) { - // Calculate the messages to display about time remaining and late submissions. - if (this.assign.duedate > 0) { - if (this.assign.duedate - time <= 0) { - this.timeRemaining = Translate.instant('addon.mod_assign.assignmentisdue'); - } else { - this.timeRemaining = CoreTimeUtils.formatDuration(this.assign.duedate - time, 3); - - if (this.assign.cutoffdate) { - if (this.assign.cutoffdate > time) { - this.lateSubmissions = Translate.instant( - 'addon.mod_assign.latesubmissionsaccepted', - { $a: CoreTimeUtils.userDate(this.assign.cutoffdate * 1000) }, - ); - } else { - this.lateSubmissions = Translate.instant('addon.mod_assign.nomoresubmissionsaccepted'); - } - } else { - this.lateSubmissions = ''; - } - } + // Calculate the messages to display about time remaining and late submissions. + if (this.assign.duedate > 0) { + if (this.assign.duedate - time <= 0) { + this.timeRemaining = Translate.instant('addon.mod_assign.assignmentisdue'); } else { - this.timeRemaining = ''; - this.lateSubmissions = ''; + this.timeRemaining = CoreTimeUtils.formatDuration(this.assign.duedate - time, 3); + + if (this.assign.cutoffdate) { + if (this.assign.cutoffdate > time) { + this.lateSubmissions = Translate.instant( + 'addon.mod_assign.latesubmissionsaccepted', + { $a: CoreTimeUtils.userDate(this.assign.cutoffdate * 1000) }, + ); + } else { + this.lateSubmissions = Translate.instant('addon.mod_assign.nomoresubmissionsaccepted'); + } + } else { + this.lateSubmissions = ''; + } } - - // Check if groupmode is enabled to avoid showing wrong numbers. - this.groupInfo = await CoreGroups.getActivityGroupInfo(this.assign.cmid, false); - - await this.setGroup(CoreGroups.validateGroupId(this.group, this.groupInfo)); - - return; + } else { + this.timeRemaining = ''; + this.lateSubmissions = ''; } - try { - // Check if the user can view their own submission. - await AddonModAssign.getSubmissionStatus(this.assign.id, { cmId: this.module.id }); - this.canViewOwnSubmission = true; - } catch (error) { - this.canViewOwnSubmission = false; + // Check if groupmode is enabled to avoid showing wrong numbers. + this.groupInfo = await CoreGroups.getActivityGroupInfo(this.assign.cmid, false); - if (error.errorcode !== 'nopermission') { - throw error; - } + await this.setGroup(CoreGroups.validateGroupId(this.group, this.groupInfo)); + + return; + } + + try { + // Check if the user can view their own submission. + await AddonModAssign.getSubmissionStatus(this.assign.id, { cmId: this.module.id }); + this.canViewOwnSubmission = true; + } catch (error) { + this.canViewOwnSubmission = false; + + if (error.errorcode !== 'nopermission') { + throw error; } - } finally { - this.fillContextMenu(refresh); } } diff --git a/src/addons/mod/bigbluebuttonbn/components/index/index.html b/src/addons/mod/bigbluebuttonbn/components/index/index.html index e10694728..e46bb4a56 100644 --- a/src/addons/mod/bigbluebuttonbn/components/index/index.html +++ b/src/addons/mod/bigbluebuttonbn/components/index/index.html @@ -1,23 +1,5 @@ - - - - - - - - - - - - - diff --git a/src/addons/mod/bigbluebuttonbn/components/index/index.ts b/src/addons/mod/bigbluebuttonbn/components/index/index.ts index 16ff70143..8d85abf94 100644 --- a/src/addons/mod/bigbluebuttonbn/components/index/index.ts +++ b/src/addons/mod/bigbluebuttonbn/components/index/index.ts @@ -71,21 +71,18 @@ export class AddonModBBBIndexComponent extends CoreCourseModuleMainActivityCompo /** * @inheritdoc */ - protected async fetchContent(refresh: boolean = false): Promise { - try { - this.bbb = await AddonModBBB.getBBB(this.courseId, this.module.id); + protected async fetchContent(): Promise { + this.bbb = await AddonModBBB.getBBB(this.courseId, this.module.id); - this.description = this.bbb.intro; - this.dataRetrieved.emit(this.bbb); + this.description = this.bbb.intro; + this.dataRetrieved.emit(this.bbb); - this.groupInfo = await CoreGroups.getActivityGroupInfo(this.module.id, false); + this.groupInfo = await CoreGroups.getActivityGroupInfo(this.module.id, false); - this.groupId = CoreGroups.validateGroupId(this.groupId, this.groupInfo); + this.groupId = CoreGroups.validateGroupId(this.groupId, this.groupInfo); + + await this.fetchMeetingInfo(); - await this.fetchMeetingInfo(); - } finally { - this.fillContextMenu(refresh); - } } /** diff --git a/src/addons/mod/book/components/index/addon-mod-book-index.html b/src/addons/mod/book/components/index/addon-mod-book-index.html index 4e1084b7a..c673defcf 100644 --- a/src/addons/mod/book/components/index/addon-mod-book-index.html +++ b/src/addons/mod/book/components/index/addon-mod-book-index.html @@ -1,21 +1,5 @@ - - - - - - - - - - diff --git a/src/addons/mod/book/components/index/index.ts b/src/addons/mod/book/components/index/index.ts index 4ef609091..b8d7f4bea 100644 --- a/src/addons/mod/book/components/index/index.ts +++ b/src/addons/mod/book/components/index/index.ts @@ -52,15 +52,11 @@ export class AddonModBookIndexComponent extends CoreCourseModuleMainResourceComp /** * @inheritdoc */ - protected async fetchContent(refresh?: boolean): Promise { - try { - await Promise.all([ - this.loadBook(), - this.loadTOC(), - ]); - } finally { - this.fillContextMenu(refresh); - } + protected async fetchContent(): Promise { + await Promise.all([ + this.loadBook(), + this.loadTOC(), + ]); } /** diff --git a/src/addons/mod/chat/components/index/addon-mod-chat-index.html b/src/addons/mod/chat/components/index/addon-mod-chat-index.html index 5851b8e75..43db1e541 100644 --- a/src/addons/mod/chat/components/index/addon-mod-chat-index.html +++ b/src/addons/mod/chat/components/index/addon-mod-chat-index.html @@ -1,27 +1,5 @@ - - - - - - - - - - - - - - - diff --git a/src/addons/mod/chat/components/index/index.ts b/src/addons/mod/chat/components/index/index.ts index fe6a7dd65..159f4e462 100644 --- a/src/addons/mod/chat/components/index/index.ts +++ b/src/addons/mod/chat/components/index/index.ts @@ -70,27 +70,23 @@ export class AddonModChatIndexComponent extends CoreCourseModuleMainActivityComp /** * @inheritdoc */ - protected async fetchContent(refresh: boolean = false): Promise { - try { - this.chat = await AddonModChat.getChat(this.courseId, this.module.id); + protected async fetchContent(): Promise { + this.chat = await AddonModChat.getChat(this.courseId, this.module.id); - this.description = this.chat.intro; - const now = CoreTimeUtils.timestamp(); - const span = (this.chat.chattime || 0) - now; + this.description = this.chat.intro; + const now = CoreTimeUtils.timestamp(); + const span = (this.chat.chattime || 0) - now; - if (this.chat.chattime && this.chat.schedule && span > 0) { - this.chatInfo = { - date: CoreTimeUtils.userDate(this.chat.chattime * 1000), - fromnow: CoreTimeUtils.formatTime(span), - }; - } else { - this.chatInfo = undefined; - } - - this.dataRetrieved.emit(this.chat); - } finally { - this.fillContextMenu(refresh); + if (this.chat.chattime && this.chat.schedule && span > 0) { + this.chatInfo = { + date: CoreTimeUtils.userDate(this.chat.chattime * 1000), + fromnow: CoreTimeUtils.formatTime(span), + }; + } else { + this.chatInfo = undefined; } + + this.dataRetrieved.emit(this.chat); } /** diff --git a/src/addons/mod/choice/components/index/addon-mod-choice-index.html b/src/addons/mod/choice/components/index/addon-mod-choice-index.html index 4b32c2dbf..15cdfbec4 100644 --- a/src/addons/mod/choice/components/index/addon-mod-choice-index.html +++ b/src/addons/mod/choice/components/index/addon-mod-choice-index.html @@ -1,29 +1,5 @@ - - - - - - - - - - - - - - - - - diff --git a/src/addons/mod/choice/components/index/index.ts b/src/addons/mod/choice/components/index/index.ts index 171ebf8fa..2597bde19 100644 --- a/src/addons/mod/choice/components/index/index.ts +++ b/src/addons/mod/choice/components/index/index.ts @@ -132,43 +132,39 @@ export class AddonModChoiceIndexComponent extends CoreCourseModuleMainActivityCo /** * @inheritdoc */ - protected async fetchContent(refresh: boolean = false, sync: boolean = false, showErrors: boolean = false): Promise { + protected async fetchContent(refresh?: boolean, sync = false, showErrors = false): Promise { this.now = Date.now(); - try { - this.choice = await AddonModChoice.getChoice(this.courseId, this.module.id); + this.choice = await AddonModChoice.getChoice(this.courseId, this.module.id); - if (sync) { - // Try to synchronize the choice. - const updated = await this.syncActivity(showErrors); + if (sync) { + // Try to synchronize the choice. + const updated = await this.syncActivity(showErrors); - if (updated) { - // Responses were sent, update the choice. - this.choice = await AddonModChoice.getChoice(this.courseId, this.module.id); - } + if (updated) { + // Responses were sent, update the choice. + this.choice = await AddonModChoice.getChoice(this.courseId, this.module.id); } - - this.choice.timeopen = (this.choice.timeopen || 0) * 1000; - this.choice.timeclose = (this.choice.timeclose || 0) * 1000; - this.openTimeReadable = CoreTimeUtils.userDate(this.choice.timeopen); - this.closeTimeReadable = CoreTimeUtils.userDate(this.choice.timeclose); - - this.description = this.choice.intro; - this.choiceNotOpenYet = !!this.choice.timeopen && this.choice.timeopen > this.now; - this.choiceClosed = !!this.choice.timeclose && this.choice.timeclose <= this.now; - - this.dataRetrieved.emit(this.choice); - - // Check if there are responses stored in offline. - this.hasOffline = await AddonModChoiceOffline.hasResponse(this.choice.id); - - // We need fetchOptions to finish before calling fetchResults because it needs hasAnsweredOnline variable. - await this.fetchOptions(this.choice); - - await this.fetchResults(this.choice); - } finally { - this.fillContextMenu(refresh); } + + this.choice.timeopen = (this.choice.timeopen || 0) * 1000; + this.choice.timeclose = (this.choice.timeclose || 0) * 1000; + this.openTimeReadable = CoreTimeUtils.userDate(this.choice.timeopen); + this.closeTimeReadable = CoreTimeUtils.userDate(this.choice.timeclose); + + this.description = this.choice.intro; + this.choiceNotOpenYet = !!this.choice.timeopen && this.choice.timeopen > this.now; + this.choiceClosed = !!this.choice.timeclose && this.choice.timeclose <= this.now; + + this.dataRetrieved.emit(this.choice); + + // Check if there are responses stored in offline. + this.hasOffline = await AddonModChoiceOffline.hasResponse(this.choice.id); + + // We need fetchOptions to finish before calling fetchResults because it needs hasAnsweredOnline variable. + await this.fetchOptions(this.choice); + + await this.fetchResults(this.choice); } /** @@ -433,7 +429,7 @@ export class AddonModChoiceIndexComponent extends CoreCourseModuleMainActivityCo * @return Promise resolved when done. */ protected async dataUpdated(online: boolean): Promise { - if (!online || !this.isPrefetched) { + if (!online || !this.isPrefetched()) { // Not downloaded, just refresh the data. return this.refreshContent(false); } diff --git a/src/addons/mod/data/components/index/addon-mod-data-index.html b/src/addons/mod/data/components/index/addon-mod-data-index.html index b64adbce8..a80142873 100644 --- a/src/addons/mod/data/components/index/addon-mod-data-index.html +++ b/src/addons/mod/data/components/index/addon-mod-data-index.html @@ -4,34 +4,12 @@ - - - - - - - - - - - - - - diff --git a/src/addons/mod/data/components/index/index.ts b/src/addons/mod/data/components/index/index.ts index 3386cbd82..543cceeda 100644 --- a/src/addons/mod/data/components/index/index.ts +++ b/src/addons/mod/data/components/index/index.ts @@ -202,14 +202,9 @@ export class AddonModDataIndexComponent extends CoreCourseModuleMainActivityComp } /** - * Download data contents. - * - * @param refresh If it's refreshing content. - * @param sync If it should try to sync. - * @param showErrors If show errors to the user of hide them. - * @return Promise resolved when done. + * @inheritdoc */ - protected async fetchContent(refresh: boolean = false, sync: boolean = false, showErrors: boolean = false): Promise { + protected async fetchContent(refresh?: boolean, sync = false, showErrors = false): Promise { let canAdd = false; let canSearch = false; @@ -270,7 +265,6 @@ export class AddonModDataIndexComponent extends CoreCourseModuleMainActivityComp } finally { this.canAdd = canAdd; this.canSearch = canSearch; - this.fillContextMenu(refresh); } } diff --git a/src/addons/mod/feedback/components/index/addon-mod-feedback-index.html b/src/addons/mod/feedback/components/index/addon-mod-feedback-index.html index bb3b4550e..eb54799b8 100644 --- a/src/addons/mod/feedback/components/index/addon-mod-feedback-index.html +++ b/src/addons/mod/feedback/components/index/addon-mod-feedback-index.html @@ -1,29 +1,5 @@ - - - - - - - - - - - - - - - - - diff --git a/src/addons/mod/feedback/components/index/index.ts b/src/addons/mod/feedback/components/index/index.ts index 3f3f94027..255b0e6ce 100644 --- a/src/addons/mod/feedback/components/index/index.ts +++ b/src/addons/mod/feedback/components/index/index.ts @@ -172,7 +172,7 @@ export class AddonModFeedbackIndexComponent extends CoreCourseModuleMainActivity /** * @inheritdoc */ - protected async fetchContent(refresh: boolean = false, sync: boolean = false, showErrors: boolean = false): Promise { + protected async fetchContent(refresh?: boolean, sync = false, showErrors = false): Promise { try { this.feedback = await AddonModFeedback.getFeedback(this.courseId, this.module.id); @@ -201,9 +201,6 @@ export class AddonModFeedbackIndexComponent extends CoreCourseModuleMainActivity await this.fetchFeedbackOverviewData(); } finally { - // Now fill the context menu. - this.fillContextMenu(refresh); - if (this.feedback) { // Check if there are responses stored in offline. this.hasOffline = await AddonModFeedbackOffline.hasFeedbackOfflineData(this.feedback.id); diff --git a/src/addons/mod/folder/components/index/addon-mod-folder-index.html b/src/addons/mod/folder/components/index/addon-mod-folder-index.html index ea4d48cdf..e50f4f51b 100644 --- a/src/addons/mod/folder/components/index/addon-mod-folder-index.html +++ b/src/addons/mod/folder/components/index/addon-mod-folder-index.html @@ -1,26 +1,5 @@ - - - - - - - - - - - - - - - diff --git a/src/addons/mod/folder/components/index/index.ts b/src/addons/mod/folder/components/index/index.ts index 73cdb6271..562a2824e 100644 --- a/src/addons/mod/folder/components/index/index.ts +++ b/src/addons/mod/folder/components/index/index.ts @@ -12,7 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { CoreConstants } from '@/core/constants'; import { Component, Input, OnInit, Optional } from '@angular/core'; import { Params } from '@angular/router'; import { CoreCourseModuleMainResourceComponent } from '@features/course/classes/main-resource-component'; @@ -57,7 +56,6 @@ export class AddonModFolderIndexComponent extends CoreCourseModuleMainResourceCo this.contents = this.subfolder; this.loaded = true; - this.refreshIcon = CoreConstants.ICON_REFRESH; return; } @@ -73,7 +71,6 @@ export class AddonModFolderIndexComponent extends CoreCourseModuleMainResourceCo } } finally { this.loaded = true; - this.refreshIcon = CoreConstants.ICON_REFRESH; } } @@ -87,24 +84,17 @@ export class AddonModFolderIndexComponent extends CoreCourseModuleMainResourceCo } /** - * Download folder contents. - * - * @param refresh Whether we're refreshing data. - * @return Promise resolved when done. + * @inheritdoc */ protected async fetchContent(refresh = false): Promise { - try { - this.folderInstance = await AddonModFolder.getFolder(this.courseId, this.module.id); + this.folderInstance = await AddonModFolder.getFolder(this.courseId, this.module.id); - const contents = await CoreCourse.getModuleContents(this.module, undefined, undefined, false, refresh); + const contents = await CoreCourse.getModuleContents(this.module, undefined, undefined, false, refresh); - this.dataRetrieved.emit(this.folderInstance || this.module); + this.dataRetrieved.emit(this.folderInstance || this.module); - this.description = this.folderInstance ? this.folderInstance.intro : this.module.description; - this.contents = AddonModFolderHelper.formatContents(contents); - } finally { - this.fillContextMenu(refresh); - } + this.description = this.folderInstance ? this.folderInstance.intro : this.module.description; + this.contents = AddonModFolderHelper.formatContents(contents); } /** diff --git a/src/addons/mod/forum/components/index/index.html b/src/addons/mod/forum/components/index/index.html index 3bd8b6ada..b16a7b9d4 100644 --- a/src/addons/mod/forum/components/index/index.html +++ b/src/addons/mod/forum/components/index/index.html @@ -1,29 +1,6 @@ - - - - - - - - - - - - - - diff --git a/src/addons/mod/forum/components/index/index.ts b/src/addons/mod/forum/components/index/index.ts index 3c8337d41..40fda05ae 100644 --- a/src/addons/mod/forum/components/index/index.ts +++ b/src/addons/mod/forum/components/index/index.ts @@ -296,13 +296,9 @@ export class AddonModForumIndexComponent extends CoreCourseModuleMainActivityCom } /** - * Download the component contents. - * - * @param refresh Whether we're refreshing data. - * @param sync If the refresh needs syncing. - * @param showErrors Wether to show errors to the user or hide them. + * @inheritdoc */ - protected async fetchContent(refresh: boolean = false, sync: boolean = false, showErrors: boolean = false): Promise { + protected async fetchContent(refresh = false, sync = false, showErrors = false): Promise { this.fetchFailed = false; try { @@ -329,8 +325,6 @@ export class AddonModForumIndexComponent extends CoreCourseModuleMainActivityCom this.fetchFailed = true; // Set to prevent infinite calls with infinite-loading. throw error; // Pass the error to the parent catch. - } finally { - this.fillContextMenu(refresh); } } diff --git a/src/addons/mod/forum/lang.json b/src/addons/mod/forum/lang.json index 11f77ca53..86e48abf7 100644 --- a/src/addons/mod/forum/lang.json +++ b/src/addons/mod/forum/lang.json @@ -50,7 +50,6 @@ "posttomygroups": "Post a copy to all groups", "privatereply": "Reply privately", "re": "Re:", - "refreshdiscussions": "Refresh discussions", "refreshposts": "Refresh posts", "removefromfavourites": "Unstar this discussion", "reply": "Reply", diff --git a/src/addons/mod/glossary/components/index/addon-mod-glossary-index.html b/src/addons/mod/glossary/components/index/addon-mod-glossary-index.html index 142f410eb..2341c36e7 100644 --- a/src/addons/mod/glossary/components/index/addon-mod-glossary-index.html +++ b/src/addons/mod/glossary/components/index/addon-mod-glossary-index.html @@ -10,31 +10,9 @@ - - - - - - - - - - - - - - diff --git a/src/addons/mod/glossary/components/index/index.ts b/src/addons/mod/glossary/components/index/index.ts index 7cf42ded3..cbcc5aa89 100644 --- a/src/addons/mod/glossary/components/index/index.ts +++ b/src/addons/mod/glossary/components/index/index.ts @@ -177,39 +177,35 @@ export class AddonModGlossaryIndexComponent extends CoreCourseModuleMainActivity /** * @inheritdoc */ - protected async fetchContent(refresh: boolean = false, sync: boolean = false, showErrors: boolean = false): Promise { + protected async fetchContent(refresh = false, sync = false, showErrors = false): Promise { const entries = await this.promisedEntries; - try { - await entries.getSource().loadGlossary(); + await entries.getSource().loadGlossary(); - if (!this.glossary) { - return; - } - - this.description = this.glossary.intro || this.description; - this.canAdd = !!this.glossary.canaddentry || false; - - this.dataRetrieved.emit(this.glossary); - - if (!entries.getSource().fetchMode) { - this.switchMode('letter_all'); - } - - if (sync) { - // Try to synchronize the glossary. - await this.syncActivity(showErrors); - } - - const [hasOfflineRatings] = await Promise.all([ - CoreRatingOffline.hasRatings('mod_glossary', 'entry', ContextLevel.MODULE, this.glossary.coursemodule), - refresh ? entries.reload() : entries.load(), - ]); - - this.hasOfflineRatings = hasOfflineRatings; - } finally { - this.fillContextMenu(refresh); + if (!this.glossary) { + return; } + + this.description = this.glossary.intro || this.description; + this.canAdd = !!this.glossary.canaddentry || false; + + this.dataRetrieved.emit(this.glossary); + + if (!entries.getSource().fetchMode) { + this.switchMode('letter_all'); + } + + if (sync) { + // Try to synchronize the glossary. + await this.syncActivity(showErrors); + } + + const [hasOfflineRatings] = await Promise.all([ + CoreRatingOffline.hasRatings('mod_glossary', 'entry', ContextLevel.MODULE, this.glossary.coursemodule), + refresh ? entries.reload() : entries.load(), + ]); + + this.hasOfflineRatings = hasOfflineRatings; } /** diff --git a/src/addons/mod/h5pactivity/components/index/addon-mod-h5pactivity-index.html b/src/addons/mod/h5pactivity/components/index/addon-mod-h5pactivity-index.html index e7b6e7ea2..fc7dfb9ed 100644 --- a/src/addons/mod/h5pactivity/components/index/addon-mod-h5pactivity-index.html +++ b/src/addons/mod/h5pactivity/components/index/addon-mod-h5pactivity-index.html @@ -3,31 +3,10 @@ + iconAction="fas-chart-bar"> - - - - - - - - - - - - - - + (action)="viewAllAttempts()" iconAction="fas-chart-bar"> diff --git a/src/addons/mod/h5pactivity/components/index/index.ts b/src/addons/mod/h5pactivity/components/index/index.ts index f8cb4d015..834a623a7 100644 --- a/src/addons/mod/h5pactivity/components/index/index.ts +++ b/src/addons/mod/h5pactivity/components/index/index.ts @@ -112,51 +112,47 @@ export class AddonModH5PActivityIndexComponent extends CoreCourseModuleMainActiv /** * @inheritdoc */ - protected async fetchContent(refresh: boolean = false, sync: boolean = false, showErrors: boolean = false): Promise { - try { - this.h5pActivity = await AddonModH5PActivity.getH5PActivity(this.courseId, this.module.id, { - siteId: this.siteId, - }); + protected async fetchContent(refresh?: boolean, sync = false, showErrors = false): Promise { + this.h5pActivity = await AddonModH5PActivity.getH5PActivity(this.courseId, this.module.id, { + siteId: this.siteId, + }); - this.dataRetrieved.emit(this.h5pActivity); - this.description = this.h5pActivity.intro; - this.displayOptions = CoreH5PHelper.decodeDisplayOptions(this.h5pActivity.displayoptions); + this.dataRetrieved.emit(this.h5pActivity); + this.description = this.h5pActivity.intro; + this.displayOptions = CoreH5PHelper.decodeDisplayOptions(this.h5pActivity.displayoptions); - if (sync) { - await this.syncActivity(showErrors); - } + if (sync) { + await this.syncActivity(showErrors); + } - await Promise.all([ - this.checkHasOffline(), - this.fetchAccessInfo(), - this.fetchDeployedFileData(), - ]); + await Promise.all([ + this.checkHasOffline(), + this.fetchAccessInfo(), + this.fetchDeployedFileData(), + ]); - this.trackComponent = this.accessInfo?.cansubmit ? AddonModH5PActivityProvider.TRACK_COMPONENT : ''; - this.canViewAllAttempts = !!this.h5pActivity.enabletracking && !!this.accessInfo?.canreviewattempts && + this.trackComponent = this.accessInfo?.cansubmit ? AddonModH5PActivityProvider.TRACK_COMPONENT : ''; + this.canViewAllAttempts = !!this.h5pActivity.enabletracking && !!this.accessInfo?.canreviewattempts && AddonModH5PActivity.canGetUsersAttemptsInSite(); - if (this.h5pActivity.package && this.h5pActivity.package[0]) { - // The online player should use the original file, not the trusted one. - this.onlinePlayerUrl = CoreH5P.h5pPlayer.calculateOnlinePlayerUrl( - this.site.getURL(), - this.h5pActivity.package[0].fileurl, - this.displayOptions, - this.trackComponent, - ); - } + if (this.h5pActivity.package && this.h5pActivity.package[0]) { + // The online player should use the original file, not the trusted one. + this.onlinePlayerUrl = CoreH5P.h5pPlayer.calculateOnlinePlayerUrl( + this.site.getURL(), + this.h5pActivity.package[0].fileurl, + this.displayOptions, + this.trackComponent, + ); + } - if (!this.siteCanDownload || this.state == CoreConstants.DOWNLOADED) { - // Cannot download the file or already downloaded, play the package directly. - this.play(); + if (!this.siteCanDownload || this.state == CoreConstants.DOWNLOADED) { + // Cannot download the file or already downloaded, play the package directly. + this.play(); - } else if ((this.state == CoreConstants.NOT_DOWNLOADED || this.state == CoreConstants.OUTDATED) && CoreApp.isOnline() && + } else if ((this.state == CoreConstants.NOT_DOWNLOADED || this.state == CoreConstants.OUTDATED) && CoreApp.isOnline() && this.deployedFile?.filesize && CoreFilepool.shouldDownload(this.deployedFile.filesize)) { - // Package is small, download it automatically. Don't block this function for this. - this.downloadAutomatically(); - } - } finally { - this.fillContextMenu(refresh); + // Package is small, download it automatically. Don't block this function for this. + this.downloadAutomatically(); } } @@ -529,19 +525,6 @@ export class AddonModH5PActivityIndexComponent extends CoreCourseModuleMainActiv this.checkHasOffline(); } - /** - * @inheritdoc - */ - async gotoBlog(): Promise { - this.isOpeningPage = true; - - try { - await super.gotoBlog(); - } finally { - this.isOpeningPage = false; - } - } - /** * Component destroyed. */ diff --git a/src/addons/mod/imscp/components/index/addon-mod-imscp-index.html b/src/addons/mod/imscp/components/index/addon-mod-imscp-index.html index b6856d0db..a8d3096cf 100644 --- a/src/addons/mod/imscp/components/index/addon-mod-imscp-index.html +++ b/src/addons/mod/imscp/components/index/addon-mod-imscp-index.html @@ -3,26 +3,6 @@ - - - - - - - - - - - - - - diff --git a/src/addons/mod/imscp/components/index/index.ts b/src/addons/mod/imscp/components/index/index.ts index 0b6ae75a5..78df65bac 100644 --- a/src/addons/mod/imscp/components/index/index.ts +++ b/src/addons/mod/imscp/components/index/index.ts @@ -39,6 +39,7 @@ export class AddonModImscpIndexComponent extends CoreCourseModuleMainResourceCom protected items: AddonModImscpTocItem[] = []; protected currentHref?: string; + protected displayDescription = false; constructor(@Optional() courseContentsPage?: CoreCourseContentsPage) { super('AddonModImscpIndexComponent', courseContentsPage); @@ -70,42 +71,33 @@ export class AddonModImscpIndexComponent extends CoreCourseModuleMainResourceCom } /** - * Download imscp contents. - * - * @param refresh Whether we're refreshing data. - * @return Promise resolved when done. + * @inheritdoc */ protected async fetchContent(refresh = false): Promise { - try { - const downloadResult = await this.downloadResourceIfNeeded(refresh); + const downloadResult = await this.downloadResourceIfNeeded(refresh); - const imscp = await AddonModImscp.getImscp(this.courseId, this.module.id); - this.description = imscp.intro; - this.dataRetrieved.emit(imscp); + const imscp = await AddonModImscp.getImscp(this.courseId, this.module.id); + this.description = imscp.intro; + this.dataRetrieved.emit(imscp); - // Get contents. No need to refresh, it has been done in downloadResourceIfNeeded. - const contents = await CoreCourse.getModuleContents(this.module); + // Get contents. No need to refresh, it has been done in downloadResourceIfNeeded. + const contents = await CoreCourse.getModuleContents(this.module); - this.items = AddonModImscp.createItemList(contents); + this.items = AddonModImscp.createItemList(contents); - if (this.items.length && this.currentHref === undefined) { - this.currentHref = this.items[0].href; - } - - try { - await this.loadItemHref(this.currentHref); - } catch (error) { - CoreDomUtils.showErrorModalDefault(error, 'addon.mod_imscp.deploymenterror', true); - - throw new CoreSilentError(error); - } - - this.warning = downloadResult.failed ? this.getErrorDownloadingSomeFilesMessage(downloadResult.error!) : ''; - - } finally { - // Pass false because downloadResourceIfNeeded already invalidates and refresh data if refresh=true. - this.fillContextMenu(false); + if (this.items.length && this.currentHref === undefined) { + this.currentHref = this.items[0].href; } + + try { + await this.loadItemHref(this.currentHref); + } catch (error) { + CoreDomUtils.showErrorModalDefault(error, 'addon.mod_imscp.deploymenterror', true); + + throw new CoreSilentError(error); + } + + this.warning = downloadResult.failed ? this.getErrorDownloadingSomeFilesMessage(downloadResult.error!) : ''; } /** diff --git a/src/addons/mod/lesson/components/index/addon-mod-lesson-index.html b/src/addons/mod/lesson/components/index/addon-mod-lesson-index.html index dd57d8860..350ed2e21 100644 --- a/src/addons/mod/lesson/components/index/addon-mod-lesson-index.html +++ b/src/addons/mod/lesson/components/index/addon-mod-lesson-index.html @@ -1,29 +1,5 @@ - - - - - - - - - - - - - - - - - diff --git a/src/addons/mod/lesson/components/index/index.ts b/src/addons/mod/lesson/components/index/index.ts index 522d769fa..8c3a34a4a 100644 --- a/src/addons/mod/lesson/components/index/index.ts +++ b/src/addons/mod/lesson/components/index/index.ts @@ -136,85 +136,76 @@ export class AddonModLessonIndexComponent extends CoreCourseModuleMainActivityCo } /** - * Get the lesson data. - * - * @param refresh If it's refreshing content. - * @param sync If it should try to sync. - * @param showErrors If show errors to the user of hide them. - * @return Promise resolved when done. + * @inheritdoc */ - protected async fetchContent(refresh: boolean = false, sync: boolean = false, showErrors: boolean = false): Promise { - try { - let lessonReady = true; - this.askPassword = false; + protected async fetchContent(refresh?: boolean, sync = false, showErrors = false): Promise { + let lessonReady = true; + this.askPassword = false; - this.lesson = await AddonModLesson.getLesson(this.courseId, this.module.id); + this.lesson = await AddonModLesson.getLesson(this.courseId, this.module.id); - this.dataRetrieved.emit(this.lesson); - this.description = this.lesson.intro; // Show description only if intro is present. + this.dataRetrieved.emit(this.lesson); + this.description = this.lesson.intro; // Show description only if intro is present. - if (sync) { - // Try to synchronize the lesson. - await this.syncActivity(showErrors); - } + if (sync) { + // Try to synchronize the lesson. + await this.syncActivity(showErrors); + } - this.accessInfo = await AddonModLesson.getAccessInformation(this.lesson.id, { cmId: this.module.id }); - this.canManage = this.accessInfo.canmanage; - this.canViewReports = this.accessInfo.canviewreports; - this.preventReasons = []; - const promises: Promise[] = []; + this.accessInfo = await AddonModLesson.getAccessInformation(this.lesson.id, { cmId: this.module.id }); + this.canManage = this.accessInfo.canmanage; + this.canViewReports = this.accessInfo.canviewreports; + this.preventReasons = []; + const promises: Promise[] = []; - if (AddonModLesson.isLessonOffline(this.lesson)) { - // Handle status. - this.setStatusListener(); + if (AddonModLesson.isLessonOffline(this.lesson)) { + // Handle status. + this.setStatusListener(); - promises.push(this.loadOfflineData()); - } + promises.push(this.loadOfflineData()); + } - if (this.accessInfo.preventaccessreasons.length) { - let preventReason = AddonModLesson.getPreventAccessReason(this.accessInfo, false); - const askPassword = preventReason?.reason == 'passwordprotectedlesson'; + if (this.accessInfo.preventaccessreasons.length) { + let preventReason = AddonModLesson.getPreventAccessReason(this.accessInfo, false); + const askPassword = preventReason?.reason == 'passwordprotectedlesson'; - if (askPassword) { - try { - // The lesson requires a password. Check if there is one in memory or DB. - const password = this.password ? - this.password : - await AddonModLesson.getStoredPassword(this.lesson.id); + if (askPassword) { + try { + // The lesson requires a password. Check if there is one in memory or DB. + const password = this.password ? + this.password : + await AddonModLesson.getStoredPassword(this.lesson.id); - await this.validatePassword(password); + await this.validatePassword(password); - // Now that we have the password, get the access reason again ignoring the password. - preventReason = AddonModLesson.getPreventAccessReason(this.accessInfo, true); - if (preventReason) { - this.preventReasons = [preventReason]; - } - } catch { - // No password or the validation failed. Show password form. - this.askPassword = true; - this.preventReasons = [preventReason!]; - lessonReady = false; + // Now that we have the password, get the access reason again ignoring the password. + preventReason = AddonModLesson.getPreventAccessReason(this.accessInfo, true); + if (preventReason) { + this.preventReasons = [preventReason]; } - } else { - // Lesson cannot be started. + } catch { + // No password or the validation failed. Show password form. + this.askPassword = true; this.preventReasons = [preventReason!]; lessonReady = false; } + } else { + // Lesson cannot be started. + this.preventReasons = [preventReason!]; + lessonReady = false; } + } - if (this.selectedTab == 1 && this.canViewReports) { - // Only fetch the report data if the tab is selected. - promises.push(this.fetchReportData()); - } + if (this.selectedTab == 1 && this.canViewReports) { + // Only fetch the report data if the tab is selected. + promises.push(this.fetchReportData()); + } - await Promise.all(promises); + await Promise.all(promises); - if (lessonReady) { - // Lesson can be started, don't ask the password and don't show prevent messages. - this.lessonReady(); - } - } finally { - this.fillContextMenu(refresh); + if (lessonReady) { + // Lesson can be started, don't ask the password and don't show prevent messages. + this.lessonReady(); } } @@ -633,8 +624,6 @@ export class AddonModLessonIndexComponent extends CoreCourseModuleMainActivityCo } this.loaded = false; - this.refreshIcon = CoreConstants.ICON_LOADING; - this.syncIcon = CoreConstants.ICON_LOADING; try { await this.validatePassword( password); @@ -652,8 +641,6 @@ export class AddonModLessonIndexComponent extends CoreCourseModuleMainActivityCo CoreDomUtils.showErrorModal(error); } finally { this.loaded = true; - this.refreshIcon = CoreConstants.ICON_REFRESH; - this.syncIcon = CoreConstants.ICON_SYNC; CoreForms.triggerFormSubmittedEvent(this.formElement, true, this.siteId); } diff --git a/src/addons/mod/lti/components/index/addon-mod-lti-index.html b/src/addons/mod/lti/components/index/addon-mod-lti-index.html index 9dfc934b2..9892dd3ae 100644 --- a/src/addons/mod/lti/components/index/addon-mod-lti-index.html +++ b/src/addons/mod/lti/components/index/addon-mod-lti-index.html @@ -1,20 +1,5 @@ - - - - - - - - - - - @@ -24,7 +9,7 @@ - diff --git a/src/addons/mod/lti/components/index/index.ts b/src/addons/mod/lti/components/index/index.ts index f18244c01..333f0bb48 100644 --- a/src/addons/mod/lti/components/index/index.ts +++ b/src/addons/mod/lti/components/index/index.ts @@ -31,6 +31,7 @@ export class AddonModLtiIndexComponent extends CoreCourseModuleMainActivityCompo component = AddonModLtiProvider.COMPONENT; moduleName = 'lti'; + displayDescription = false; lti?: AddonModLtiLti; // The LTI object. @@ -55,15 +56,13 @@ export class AddonModLtiIndexComponent extends CoreCourseModuleMainActivityCompo /** * @inheritdoc */ - protected async fetchContent(refresh: boolean = false): Promise { - try { - this.lti = await AddonModLti.getLti(this.courseId, this.module.id); + protected async fetchContent(): Promise { + this.lti = await AddonModLti.getLti(this.courseId, this.module.id); - this.description = this.lti.intro; - this.dataRetrieved.emit(this.lti); - } finally { - this.fillContextMenu(refresh); - } + this.description = this.lti.intro; + + this.displayDescription = this.lti && !!this.lti.showdescriptionlaunch; + this.dataRetrieved.emit(this.lti); } /** diff --git a/src/addons/mod/page/components/index/addon-mod-page-index.html b/src/addons/mod/page/components/index/addon-mod-page-index.html index bd5f3a6ba..e17fa3571 100644 --- a/src/addons/mod/page/components/index/addon-mod-page-index.html +++ b/src/addons/mod/page/components/index/addon-mod-page-index.html @@ -1,26 +1,5 @@ - - - - - - - - - - - - - - - diff --git a/src/addons/mod/page/components/index/index.ts b/src/addons/mod/page/components/index/index.ts index dfba12b29..bbf8ac151 100644 --- a/src/addons/mod/page/components/index/index.ts +++ b/src/addons/mod/page/components/index/index.ts @@ -71,29 +71,22 @@ export class AddonModPageIndexComponent extends CoreCourseModuleMainResourceComp } /** - * Download page contents. - * - * @param refresh Whether we're refreshing data. - * @return Promise resolved when done. + * @inheritdoc */ protected async fetchContent(refresh?: boolean): Promise { - try { - // Download the resource if it needs to be downloaded. - const downloadResult = await this.downloadResourceIfNeeded(refresh); + // Download the resource if it needs to be downloaded. + const downloadResult = await this.downloadResourceIfNeeded(refresh); - // Get contents. No need to refresh, it has been done in downloadResourceIfNeeded. - const contents = await CoreCourse.getModuleContents(this.module); + // Get contents. No need to refresh, it has been done in downloadResourceIfNeeded. + const contents = await CoreCourse.getModuleContents(this.module); - const results = await Promise.all([ - this.loadPageData(), - AddonModPageHelper.getPageHtml(contents, this.module.id), - ]); + const results = await Promise.all([ + this.loadPageData(), + AddonModPageHelper.getPageHtml(contents, this.module.id), + ]); - this.contents = results[1]; - this.warning = downloadResult?.failed ? this.getErrorDownloadingSomeFilesMessage(downloadResult.error!) : ''; - } finally { - this.fillContextMenu(refresh); - } + this.contents = results[1]; + this.warning = downloadResult?.failed ? this.getErrorDownloadingSomeFilesMessage(downloadResult.error!) : ''; } /** diff --git a/src/addons/mod/quiz/components/index/addon-mod-quiz-index.html b/src/addons/mod/quiz/components/index/addon-mod-quiz-index.html index 8060c0171..4f6ec82f8 100644 --- a/src/addons/mod/quiz/components/index/addon-mod-quiz-index.html +++ b/src/addons/mod/quiz/components/index/addon-mod-quiz-index.html @@ -1,29 +1,5 @@ - - - - - - - - - - - - - - - - - @@ -214,7 +190,7 @@ {{ 'core.openinbrowser' | translate }} diff --git a/src/addons/mod/quiz/components/index/index.ts b/src/addons/mod/quiz/components/index/index.ts index 92bdfd881..1f03d876e 100644 --- a/src/addons/mod/quiz/components/index/index.ts +++ b/src/addons/mod/quiz/components/index/index.ts @@ -180,82 +180,73 @@ export class AddonModQuizIndexComponent extends CoreCourseModuleMainActivityComp } /** - * Get the quiz data. - * - * @param refresh If it's refreshing content. - * @param sync If it should try to sync. - * @param showErrors If show errors to the user of hide them. - * @return Promise resolved when done. + * @inheritdoc */ - protected async fetchContent(refresh: boolean = false, sync: boolean = false, showErrors: boolean = false): Promise { - try { - // First get the quiz instance. - const quiz = await AddonModQuiz.getQuiz(this.courseId, this.module.id); + protected async fetchContent(refresh?: boolean, sync = false, showErrors = false): Promise { + // First get the quiz instance. + const quiz = await AddonModQuiz.getQuiz(this.courseId, this.module.id); - this.gradeMethodReadable = AddonModQuiz.getQuizGradeMethod(quiz.grademethod); - this.now = Date.now(); - this.dataRetrieved.emit(quiz); - this.description = quiz.intro || this.description; - this.candidateQuiz = quiz; + this.gradeMethodReadable = AddonModQuiz.getQuizGradeMethod(quiz.grademethod); + this.now = Date.now(); + this.dataRetrieved.emit(quiz); + this.description = quiz.intro || this.description; + this.candidateQuiz = quiz; - // Try to get warnings from automatic sync. - const warnings = await AddonModQuizSync.getSyncWarnings(quiz.id); + // Try to get warnings from automatic sync. + const warnings = await AddonModQuizSync.getSyncWarnings(quiz.id); - if (warnings?.length) { - // Show warnings and delete them so they aren't shown again. - CoreDomUtils.showErrorModal(CoreTextUtils.buildMessage(warnings)); + if (warnings?.length) { + // Show warnings and delete them so they aren't shown again. + CoreDomUtils.showErrorModal(CoreTextUtils.buildMessage(warnings)); - await AddonModQuizSync.setSyncWarnings(quiz.id, []); - } - - if (AddonModQuiz.isQuizOffline(quiz)) { - if (sync) { - // Try to sync the quiz. - try { - await this.syncActivity(showErrors); - } catch { - // Ignore errors, keep getting data even if sync fails. - this.autoReview = undefined; - } - } - } else { - this.autoReview = undefined; - this.showStatusSpinner = false; - } - - if (AddonModQuiz.isQuizOffline(quiz)) { - // Handle status. - this.setStatusListener(); - - // Get last synchronization time and check if sync button should be seen. - this.syncTime = await AddonModQuizSync.getReadableSyncTime(quiz.id); - this.hasOffline = await AddonModQuizSync.hasDataToSync(quiz.id); - } - - // Get quiz access info. - this.quizAccessInfo = await AddonModQuiz.getQuizAccessInformation(quiz.id, { cmId: this.module.id }); - - this.showReviewColumn = this.quizAccessInfo.canreviewmyattempts; - this.accessRules = this.quizAccessInfo.accessrules; - this.unsupportedRules = AddonModQuiz.getUnsupportedRules(this.quizAccessInfo.activerulenames); - - if (quiz.preferredbehaviour) { - this.behaviourSupported = CoreQuestionBehaviourDelegate.isBehaviourSupported(quiz.preferredbehaviour); - } - - // Get question types in the quiz. - const types = await AddonModQuiz.getQuizRequiredQtypes(quiz.id, { cmId: this.module.id }); - - this.unsupportedQuestions = AddonModQuiz.getUnsupportedQuestions(types); - this.hasSupportedQuestions = !!types.find((type) => type != 'random' && this.unsupportedQuestions.indexOf(type) == -1); - - await this.getAttempts(quiz); - - // Quiz is ready to be shown, move it to the variable that is displayed. - this.quiz = quiz; - } finally { - this.fillContextMenu(refresh); + await AddonModQuizSync.setSyncWarnings(quiz.id, []); } + + if (AddonModQuiz.isQuizOffline(quiz)) { + if (sync) { + // Try to sync the quiz. + try { + await this.syncActivity(showErrors); + } catch { + // Ignore errors, keep getting data even if sync fails. + this.autoReview = undefined; + } + } + } else { + this.autoReview = undefined; + this.showStatusSpinner = false; + } + + if (AddonModQuiz.isQuizOffline(quiz)) { + // Handle status. + this.setStatusListener(); + + // Get last synchronization time and check if sync button should be seen. + this.syncTime = await AddonModQuizSync.getReadableSyncTime(quiz.id); + this.hasOffline = await AddonModQuizSync.hasDataToSync(quiz.id); + } + + // Get quiz access info. + this.quizAccessInfo = await AddonModQuiz.getQuizAccessInformation(quiz.id, { cmId: this.module.id }); + + this.showReviewColumn = this.quizAccessInfo.canreviewmyattempts; + this.accessRules = this.quizAccessInfo.accessrules; + this.unsupportedRules = AddonModQuiz.getUnsupportedRules(this.quizAccessInfo.activerulenames); + + if (quiz.preferredbehaviour) { + this.behaviourSupported = CoreQuestionBehaviourDelegate.isBehaviourSupported(quiz.preferredbehaviour); + } + + // Get question types in the quiz. + const types = await AddonModQuiz.getQuizRequiredQtypes(quiz.id, { cmId: this.module.id }); + + this.unsupportedQuestions = AddonModQuiz.getUnsupportedQuestions(types); + this.hasSupportedQuestions = !!types.find((type) => type != 'random' && this.unsupportedQuestions.indexOf(type) == -1); + + await this.getAttempts(quiz); + + // Quiz is ready to be shown, move it to the variable that is displayed. + this.quiz = quiz; } /** @@ -465,16 +456,12 @@ export class AddonModQuizIndexComponent extends CoreCourseModuleMainActivityComp // Refresh data. this.loaded = false; - this.refreshIcon = CoreConstants.ICON_LOADING; - this.syncIcon = CoreConstants.ICON_LOADING; this.content?.scrollToTop(); await promise; await CoreUtils.ignoreErrors(this.refreshContent(true)); this.loaded = true; - this.refreshIcon = CoreConstants.ICON_REFRESH; - this.syncIcon = CoreConstants.ICON_SYNC; } /** diff --git a/src/addons/mod/resource/components/index/addon-mod-resource-index.html b/src/addons/mod/resource/components/index/addon-mod-resource-index.html index 78357a63f..c209b8031 100644 --- a/src/addons/mod/resource/components/index/addon-mod-resource-index.html +++ b/src/addons/mod/resource/components/index/addon-mod-resource-index.html @@ -1,21 +1,5 @@ - - - - - - - - - - @@ -25,9 +9,8 @@ - + diff --git a/src/addons/mod/resource/components/index/index.ts b/src/addons/mod/resource/components/index/index.ts index 897711e19..203b2349e 100644 --- a/src/addons/mod/resource/components/index/index.ts +++ b/src/addons/mod/resource/components/index/index.ts @@ -116,76 +116,74 @@ export class AddonModResourceIndexComponent extends CoreCourseModuleMainResource throw new CoreError(Translate.instant('core.filenotfound')); } - let hasCalledDownloadResource = false; - // Get the resource instance to get the latest name/description and to know if it's embedded. const resource = await AddonModResource.getResourceData(this.courseId, this.module.id); this.description = resource.intro || ''; const options: AddonModResourceCustomData = resource.displayoptions ? CoreTextUtils.unserialize(resource.displayoptions) : {}; - try { - this.displayDescription = options.printintro === undefined || !!options.printintro; - this.dataRetrieved.emit(resource); + this.displayDescription = options.printintro === undefined || !!options.printintro; + this.dataRetrieved.emit(resource); - if (AddonModResourceHelper.isDisplayedInIframe(this.module)) { - hasCalledDownloadResource = true; + if (AddonModResourceHelper.isDisplayedInIframe(this.module)) { - const downloadResult = await this.downloadResourceIfNeeded(refresh, true); - const src = await AddonModResourceHelper.getIframeSrc(this.module); - this.mode = 'iframe'; + const downloadResult = await this.downloadResourceIfNeeded(refresh, true); + const src = await AddonModResourceHelper.getIframeSrc(this.module); + this.mode = 'iframe'; - if (this.src && src.toString() == this.src.toString()) { - // Re-loading same page. - // Set it to empty and then re-set the src in the next digest so it detects it has changed. - this.src = ''; - setTimeout(() => { - this.src = src; - }); - } else { + if (this.src && src.toString() == this.src.toString()) { + // Re-loading same page. + // Set it to empty and then re-set the src in the next digest so it detects it has changed. + this.src = ''; + setTimeout(() => { this.src = src; - } - - this.warning = downloadResult.failed - ? this.getErrorDownloadingSomeFilesMessage(downloadResult.error!) - : ''; - - return; - } - - if (resource && 'display' in resource && AddonModResourceHelper.isDisplayedEmbedded(this.module, resource.display)) { - this.mode = 'embedded'; - this.warning = ''; - - this.contentText = await AddonModResourceHelper.getEmbeddedHtml(this.module); - this.mode = this.contentText.length > 0 ? 'embedded' : 'external'; + }); } else { - this.mode = 'external'; - this.warning = ''; - let mimetype: string; - - if (this.isIOS) { - this.shouldOpenInBrowser = CoreFileHelper.shouldOpenInBrowser(contents[0]); - } - - if ('contentsinfo' in this.module && this.module.contentsinfo) { - mimetype = this.module.contentsinfo.mimetypes[0]; - this.readableSize = CoreTextUtils.bytesToSize(this.module.contentsinfo.filessize, 1); - this.timemodified = this.module.contentsinfo.lastmodified * 1000; - } else { - mimetype = await CoreUtils.getMimeTypeFromUrl(CoreFileHelper.getFileUrl(contents[0])); - this.readableSize = CoreTextUtils.bytesToSize(contents[0].filesize, 1); - this.timemodified = contents[0].timemodified * 1000; - } - - this.timecreated = contents[0].timecreated * 1000; - this.isExternalFile = !!contents[0].isexternalfile; - this.type = CoreMimetypeUtils.getMimetypeDescription(mimetype); - this.isStreamedFile = CoreMimetypeUtils.isStreamedMimetype(mimetype); + this.src = src; } - } finally { - // Pass false in some cases because downloadResourceIfNeeded already invalidates and refresh data if refresh=true. - this.fillContextMenu(hasCalledDownloadResource ? false : refresh); + + // Never show description on iframe. + this.displayDescription = false; + + this.warning = downloadResult.failed + ? this.getErrorDownloadingSomeFilesMessage(downloadResult.error!) + : ''; + + return; + } + + if (resource && 'display' in resource && AddonModResourceHelper.isDisplayedEmbedded(this.module, resource.display)) { + this.mode = 'embedded'; + this.warning = ''; + + this.contentText = await AddonModResourceHelper.getEmbeddedHtml(this.module); + this.mode = this.contentText.length > 0 ? 'embedded' : 'external'; + } else { + this.mode = 'external'; + this.warning = ''; + let mimetype: string; + + // Always show description on external. + this.displayDescription = true; + + if (this.isIOS) { + this.shouldOpenInBrowser = CoreFileHelper.shouldOpenInBrowser(contents[0]); + } + + if ('contentsinfo' in this.module && this.module.contentsinfo) { + mimetype = this.module.contentsinfo.mimetypes[0]; + this.readableSize = CoreTextUtils.bytesToSize(this.module.contentsinfo.filessize, 1); + this.timemodified = this.module.contentsinfo.lastmodified * 1000; + } else { + mimetype = await CoreUtils.getMimeTypeFromUrl(CoreFileHelper.getFileUrl(contents[0])); + this.readableSize = CoreTextUtils.bytesToSize(contents[0].filesize, 1); + this.timemodified = contents[0].timemodified * 1000; + } + + this.timecreated = contents[0].timecreated * 1000; + this.isExternalFile = !!contents[0].isexternalfile; + this.type = CoreMimetypeUtils.getMimetypeDescription(mimetype); + this.isStreamedFile = CoreMimetypeUtils.isStreamedMimetype(mimetype); } } diff --git a/src/addons/mod/scorm/components/index/addon-mod-scorm-index.html b/src/addons/mod/scorm/components/index/addon-mod-scorm-index.html index e5eea8e77..0fa5c17a4 100644 --- a/src/addons/mod/scorm/components/index/addon-mod-scorm-index.html +++ b/src/addons/mod/scorm/components/index/addon-mod-scorm-index.html @@ -1,29 +1,5 @@ - - - - - - - - - - - - - - - - - @@ -176,7 +152,7 @@

{{ errorMessage | translate }}

- + {{ 'core.openinbrowser' | translate }} diff --git a/src/addons/mod/scorm/components/index/index.ts b/src/addons/mod/scorm/components/index/index.ts index 44985f6d1..88dd7b2c8 100644 --- a/src/addons/mod/scorm/components/index/index.ts +++ b/src/addons/mod/scorm/components/index/index.ts @@ -175,43 +175,39 @@ export class AddonModScormIndexComponent extends CoreCourseModuleMainActivityCom /** * @inheritdoc */ - protected async fetchContent(refresh: boolean = false, sync: boolean = false, showErrors: boolean = false): Promise { - try { - // Get the SCORM instance. - this.scorm = await AddonModScorm.getScorm(this.courseId, this.module.id, { moduleUrl: this.module.url }); + protected async fetchContent(refresh?: boolean, sync = false, showErrors = false): Promise { + // Get the SCORM instance. + this.scorm = await AddonModScorm.getScorm(this.courseId, this.module.id, { moduleUrl: this.module.url }); - this.dataRetrieved.emit(this.scorm); - this.description = this.scorm.intro || this.description; - this.errorMessage = AddonModScorm.isScormUnsupported(this.scorm); + this.dataRetrieved.emit(this.scorm); + this.description = this.scorm.intro || this.description; + this.errorMessage = AddonModScorm.isScormUnsupported(this.scorm); - if (this.scorm.warningMessage) { - return; // SCORM is closed or not open yet, we can't get more data. - } + if (this.scorm.warningMessage) { + return; // SCORM is closed or not open yet, we can't get more data. + } - if (sync) { - // Try to synchronize the SCORM. - await CoreUtils.ignoreErrors(this.syncActivity(showErrors)); - } + if (sync) { + // Try to synchronize the SCORM. + await CoreUtils.ignoreErrors(this.syncActivity(showErrors)); + } - const [syncTime, accessInfo] = await Promise.all([ - AddonModScormSync.getReadableSyncTime(this.scorm.id), - AddonModScorm.getAccessInformation(this.scorm.id, { cmId: this.module.id }), - this.fetchAttemptData(this.scorm), - ]); + const [syncTime, accessInfo] = await Promise.all([ + AddonModScormSync.getReadableSyncTime(this.scorm.id), + AddonModScorm.getAccessInformation(this.scorm.id, { cmId: this.module.id }), + this.fetchAttemptData(this.scorm), + ]); - this.syncTime = syncTime; - this.accessInfo = accessInfo; + this.syncTime = syncTime; + this.accessInfo = accessInfo; - // Check whether to launch the SCORM immediately. - if (this.skip === undefined) { - this.skip = !this.hasOffline && !this.errorMessage && + // Check whether to launch the SCORM immediately. + if (this.skip === undefined) { + this.skip = !this.hasOffline && !this.errorMessage && (!this.scorm.lastattemptlock || this.attemptsLeft > 0) && this.accessInfo.canskipview && !this.accessInfo.canviewreport && this.scorm.skipview! >= AddonModScormProvider.SKIPVIEW_FIRST && (this.scorm.skipview == AddonModScormProvider.SKIPVIEW_ALWAYS || this.lastAttempt == 0); - } - } finally { - this.fillContextMenu(refresh); } } diff --git a/src/addons/mod/survey/components/index/addon-mod-survey-index.html b/src/addons/mod/survey/components/index/addon-mod-survey-index.html index 8f73a5c47..dedf029c9 100644 --- a/src/addons/mod/survey/components/index/addon-mod-survey-index.html +++ b/src/addons/mod/survey/components/index/addon-mod-survey-index.html @@ -1,30 +1,5 @@ - - - - - - - - - - - - - - - - - @@ -41,7 +16,7 @@

{{ 'addon.mod_survey.surveycompletednograph' | translate }}

- + {{ 'addon.mod_survey.results' | translate }} diff --git a/src/addons/mod/survey/components/index/index.ts b/src/addons/mod/survey/components/index/index.ts index 0be63e920..eca06619b 100644 --- a/src/addons/mod/survey/components/index/index.ts +++ b/src/addons/mod/survey/components/index/index.ts @@ -115,39 +115,30 @@ export class AddonModSurveyIndexComponent extends CoreCourseModuleMainActivityCo } /** - * Download survey contents. - * - * @param refresh If it's refreshing content. - * @param sync If it should try to sync. - * @param showErrors If show errors to the user of hide them. - * @return Promise resolved when done. + * @inheritdoc */ - protected async fetchContent(refresh: boolean = false, sync: boolean = false, showErrors: boolean = false): Promise { - try { - this.survey = await AddonModSurvey.getSurvey(this.courseId, this.module.id); + protected async fetchContent(refresh?: boolean, sync = false, showErrors = false): Promise { + this.survey = await AddonModSurvey.getSurvey(this.courseId, this.module.id); - this.description = this.survey.intro; - this.dataRetrieved.emit(this.survey); + this.description = this.survey.intro; + this.dataRetrieved.emit(this.survey); - if (sync) { - // Try to synchronize the survey. - const answersSent = await this.syncActivity(showErrors); - if (answersSent) { - // Answers were sent, update the survey. - this.survey = await AddonModSurvey.getSurvey(this.courseId, this.module.id); - } + if (sync) { + // Try to synchronize the survey. + const answersSent = await this.syncActivity(showErrors); + if (answersSent) { + // Answers were sent, update the survey. + this.survey = await AddonModSurvey.getSurvey(this.courseId, this.module.id); } + } - // Check if there are answers stored in offline. - this.hasOffline = this.survey.surveydone - ? false - : await AddonModSurveyOffline.hasAnswers(this.survey.id); + // Check if there are answers stored in offline. + this.hasOffline = this.survey.surveydone + ? false + : await AddonModSurveyOffline.hasAnswers(this.survey.id); - if (!this.survey.surveydone && !this.hasOffline) { - await this.fetchQuestions(); - } - } finally { - this.fillContextMenu(refresh); + if (!this.survey.surveydone && !this.hasOffline) { + await this.fetchQuestions(); } } diff --git a/src/addons/mod/url/components/index/addon-mod-url-index.html b/src/addons/mod/url/components/index/addon-mod-url-index.html index 47d00e1af..8b531ded4 100644 --- a/src/addons/mod/url/components/index/addon-mod-url-index.html +++ b/src/addons/mod/url/components/index/addon-mod-url-index.html @@ -1,16 +1,5 @@ - - - - - - - diff --git a/src/addons/mod/wiki/components/index/addon-mod-wiki-index.html b/src/addons/mod/wiki/components/index/addon-mod-wiki-index.html index c689ec193..de251b747 100644 --- a/src/addons/mod/wiki/components/index/addon-mod-wiki-index.html +++ b/src/addons/mod/wiki/components/index/addon-mod-wiki-index.html @@ -13,34 +13,12 @@ - - - - - - - - - - - - - - diff --git a/src/addons/mod/wiki/components/index/index.ts b/src/addons/mod/wiki/components/index/index.ts index 4f5a4709f..a9b8780de 100644 --- a/src/addons/mod/wiki/components/index/index.ts +++ b/src/addons/mod/wiki/components/index/index.ts @@ -21,14 +21,16 @@ import { CoreCourse } from '@features/course/services/course'; import { CoreTag, CoreTagItem } from '@features/tag/services/tag'; import { CoreUser } from '@features/user/services/user'; import { IonContent } from '@ionic/angular'; +import { CoreApp } from '@services/app'; import { CoreGroup, CoreGroups } from '@services/groups'; import { CoreNavigator } from '@services/navigator'; import { CoreSites } from '@services/sites'; import { CoreDomUtils } from '@services/utils/dom'; import { CoreTextUtils } from '@services/utils/text'; import { CoreUtils } from '@services/utils/utils'; -import { Translate } from '@singletons'; +import { Network, Translate, NgZone } from '@singletons'; import { CoreEventObserver, CoreEvents } from '@singletons/events'; +import { Subscription } from 'rxjs'; import { Md5 } from 'ts-md5'; import { AddonModWikiPageDBRecord } from '../../services/database/wiki'; import { AddonModWikiModuleHandlerService } from '../../services/handlers/module'; @@ -76,6 +78,8 @@ export class AddonModWikiIndexComponent extends CoreCourseModuleMainActivityComp moduleName = 'wiki'; groupWiki = false; + isOnline = false; + wiki?: AddonModWikiWiki; // The wiki instance. isMainPage = false; // Whether the user is viewing wiki's main page (just entered the wiki). canEdit = false; // Whether user can edit the page. @@ -104,12 +108,23 @@ export class AddonModWikiIndexComponent extends CoreCourseModuleMainActivityComp protected ignoreManualSyncEvent = false; // Whether manual sync event should be ignored. protected currentUserId?: number; // Current user ID. protected currentPath!: string; + protected onlineSubscription: Subscription; // It will observe the status of the network connection. constructor( protected content?: IonContent, @Optional() courseContentsPage?: CoreCourseContentsPage, ) { super('AddonModLessonIndexComponent', content, courseContentsPage); + + this.isOnline = CoreApp.isOnline(); + + // Refresh online status when changes. + this.onlineSubscription = Network.onChange().subscribe(() => { + // Execute the callback in the Angular zone, so change detection doesn't stop working. + NgZone.run(() => { + this.isOnline = CoreApp.isOnline(); + }); + }); } /** @@ -212,7 +227,7 @@ export class AddonModWikiIndexComponent extends CoreCourseModuleMainActivityComp /** * @inheritdoc */ - protected async fetchContent(refresh = false, sync = false, showErrors = false): Promise { + protected async fetchContent(refresh?: boolean, sync = false, showErrors = false): Promise { try { // Get the wiki instance. this.wiki = await AddonModWiki.getWiki(this.courseId, this.module.id); @@ -240,7 +255,6 @@ export class AddonModWikiIndexComponent extends CoreCourseModuleMainActivityComp } this.description = this.wiki.intro || this.module.description; - this.externalUrl = this.module.url; this.componentId = this.module.id; await this.fetchSubwikis(this.wiki.id); @@ -278,8 +292,6 @@ export class AddonModWikiIndexComponent extends CoreCourseModuleMainActivityComp } throw error; - } finally { - this.fillContextMenu(refresh); } } @@ -835,6 +847,7 @@ export class AddonModWikiIndexComponent extends CoreCourseModuleMainActivityComp this.manualSyncObserver?.off(); this.newPageObserver?.off(); + this.onlineSubscription.unsubscribe(); if (this.wiki) { AddonModWiki.wikiPageClosed(this.wiki.id, this.currentPath); } diff --git a/src/addons/mod/workshop/components/index/addon-mod-workshop-index.html b/src/addons/mod/workshop/components/index/addon-mod-workshop-index.html index ec5719b0d..9ff979bf8 100644 --- a/src/addons/mod/workshop/components/index/addon-mod-workshop-index.html +++ b/src/addons/mod/workshop/components/index/addon-mod-workshop-index.html @@ -1,30 +1,5 @@ - - - - - - - - - - - - - - - - - diff --git a/src/addons/mod/workshop/components/index/index.ts b/src/addons/mod/workshop/components/index/index.ts index f3cd51e4d..1376c7433 100644 --- a/src/addons/mod/workshop/components/index/index.ts +++ b/src/addons/mod/workshop/components/index/index.ts @@ -216,55 +216,45 @@ export class AddonModWorkshopIndexComponent extends CoreCourseModuleMainActivity } /** - * Download feedback contents. - * - * @param refresh If it's refreshing content. - * @param sync If it should try to sync. - * @param showErrors If show errors to the user of hide them. - * @return Promise resolved when done. + * @inheritdoc */ - protected async fetchContent(refresh = false, sync = false, showErrors = false): Promise { - try { - this.workshop = await AddonModWorkshop.getWorkshop(this.courseId, this.module.id); + protected async fetchContent(refresh?: boolean, sync = false, showErrors = false): Promise { + this.workshop = await AddonModWorkshop.getWorkshop(this.courseId, this.module.id); - this.description = this.workshop.intro; - this.dataRetrieved.emit(this.workshop); + this.description = this.workshop.intro; + this.dataRetrieved.emit(this.workshop); - if (sync) { - // Try to synchronize the feedback. - await this.syncActivity(showErrors); - } - - // Check if there are answers stored in offline. - this.access = await AddonModWorkshop.getWorkshopAccessInformation(this.workshop.id, { cmId: this.module.id }); - - if (this.access.canviewallsubmissions) { - this.groupInfo = await CoreGroups.getActivityGroupInfo(this.workshop.coursemodule); - this.group = CoreGroups.validateGroupId(this.group, this.groupInfo); - } - - this.phases = await AddonModWorkshop.getUserPlanPhases(this.workshop.id, { cmId: this.module.id }); - - this.phases[this.workshop.phase].tasks.forEach((task) => { - if (!task.link && (task.code == 'examples' || task.code == 'prepareexamples')) { - // Add links to manage examples. - task.link = this.externalUrl!; - } - }); - - // Check if there are info stored in offline. - this.hasOffline = await AddonModWorkshopOffline.hasWorkshopOfflineData(this.workshop.id); - if (this.hasOffline) { - this.offlineSubmissions = await AddonModWorkshopOffline.getSubmissions(this.workshop.id); - } else { - this.offlineSubmissions = []; - } - - await this.setPhaseInfo(); - - } finally { - this.fillContextMenu(refresh); + if (sync) { + // Try to synchronize the feedback. + await this.syncActivity(showErrors); } + + // Check if there are answers stored in offline. + this.access = await AddonModWorkshop.getWorkshopAccessInformation(this.workshop.id, { cmId: this.module.id }); + + if (this.access.canviewallsubmissions) { + this.groupInfo = await CoreGroups.getActivityGroupInfo(this.workshop.coursemodule); + this.group = CoreGroups.validateGroupId(this.group, this.groupInfo); + } + + this.phases = await AddonModWorkshop.getUserPlanPhases(this.workshop.id, { cmId: this.module.id }); + + this.phases[this.workshop.phase].tasks.forEach((task) => { + if (!task.link && (task.code == 'examples' || task.code == 'prepareexamples')) { + // Add links to manage examples. + task.link = this.module.url || ''; + } + }); + + // Check if there are info stored in offline. + this.hasOffline = await AddonModWorkshopOffline.hasWorkshopOfflineData(this.workshop.id); + if (this.hasOffline) { + this.offlineSubmissions = await AddonModWorkshopOffline.getSubmissions(this.workshop.id); + } else { + this.offlineSubmissions = []; + } + + await this.setPhaseInfo(); } /** @@ -394,7 +384,7 @@ export class AddonModWorkshopIndexComponent extends CoreCourseModuleMainActivity componentProps: { phases: CoreUtils.objectToArray(this.phases), workshopPhase: this.workshop!.phase, - externalUrl: this.externalUrl, + externalUrl: this.module.url, showSubmit: this.showSubmit, }, }); diff --git a/src/core/features/course/classes/main-activity-component.ts b/src/core/features/course/classes/main-activity-component.ts index e89d53476..d0214e996 100644 --- a/src/core/features/course/classes/main-activity-component.ts +++ b/src/core/features/course/classes/main-activity-component.ts @@ -17,15 +17,11 @@ import { IonContent } from '@ionic/angular'; import { CoreCourseModuleMainResourceComponent } from './main-resource-component'; import { CoreEventObserver, CoreEvents } from '@singletons/events'; -import { Network, NgZone } from '@singletons'; -import { Subscription } from 'rxjs'; -import { CoreApp } from '@services/app'; import { CoreCourse } from '../services/course'; import { CoreUtils } from '@services/utils/utils'; import { CoreDomUtils } from '@services/utils/dom'; import { CoreWSExternalWarning } from '@services/ws'; import { CoreCourseContentsPage } from '../pages/contents/contents'; -import { CoreConstants } from '@/core/constants'; import { CoreSites } from '@services/sites'; /** @@ -40,12 +36,7 @@ export class CoreCourseModuleMainActivityComponent extends CoreCourseModuleMainR moduleName?: string; // Raw module name to be translated. It will be translated on init. - // Data for context menu. - syncIcon?: string; // Sync icon. - isOnline?: boolean; // If the app is online or not. - protected syncObserver?: CoreEventObserver; // It will observe the sync auto event. - protected onlineSubscription: Subscription; // It will observe the status of the network connection. protected syncEventName?: string; // Auto sync event name. constructor( @@ -54,14 +45,6 @@ export class CoreCourseModuleMainActivityComponent extends CoreCourseModuleMainR courseContentsPage?: CoreCourseContentsPage, ) { super(loggerName, courseContentsPage); - - // Refresh online status when changes. - this.onlineSubscription = Network.onChange().subscribe(() => { - // Execute the callback in the Angular zone, so change detection doesn't stop working. - NgZone.run(() => { - this.isOnline = CoreApp.isOnline(); - }); - }); } /** @@ -71,7 +54,6 @@ export class CoreCourseModuleMainActivityComponent extends CoreCourseModuleMainR await super.ngOnInit(); this.hasOffline = false; - this.syncIcon = CoreConstants.ICON_LOADING; this.moduleName = CoreCourse.translateModuleName(this.moduleName || ''); if (this.syncEventName) { @@ -118,20 +100,12 @@ export class CoreCourseModuleMainActivityComponent extends CoreCourseModuleMainR return; } - this.refreshIcon = CoreConstants.ICON_LOADING; - this.syncIcon = CoreConstants.ICON_LOADING; + await CoreUtils.ignoreErrors(Promise.all([ + this.invalidateContent(), + this.showCompletion ? CoreCourse.invalidateModule(this.module.id) : undefined, + ])); - try { - await CoreUtils.ignoreErrors(Promise.all([ - this.invalidateContent(), - this.showCompletion ? CoreCourse.invalidateModule(this.module.id) : undefined, - ])); - - await this.loadContent(true, sync, showErrors); - } finally { - this.refreshIcon = CoreConstants.ICON_REFRESH; - this.syncIcon = CoreConstants.ICON_SYNC; - } + await this.loadContent(true, sync, showErrors); } /** @@ -142,17 +116,10 @@ export class CoreCourseModuleMainActivityComponent extends CoreCourseModuleMainR * @return Resolved when done. */ protected async showLoadingAndFetch(sync: boolean = false, showErrors: boolean = false): Promise { - this.refreshIcon = CoreConstants.ICON_LOADING; - this.syncIcon = CoreConstants.ICON_LOADING; this.loaded = false; this.content?.scrollToTop(); - try { - await this.loadContent(false, sync, showErrors); - } finally { - this.refreshIcon = CoreConstants.ICON_REFRESH; - this.syncIcon = CoreConstants.ICON_REFRESH; - } + await this.loadContent(false, sync, showErrors); } /** @@ -163,8 +130,6 @@ export class CoreCourseModuleMainActivityComponent extends CoreCourseModuleMainR * @return Resolved when done. */ protected showLoadingAndRefresh(sync: boolean = false, showErrors: boolean = false): Promise { - this.refreshIcon = CoreConstants.ICON_LOADING; - this.syncIcon = CoreConstants.ICON_LOADING; this.loaded = false; this.content?.scrollToTop(); @@ -193,8 +158,6 @@ export class CoreCourseModuleMainActivityComponent extends CoreCourseModuleMainR * @return Promise resolved when done. */ protected async loadContent(refresh?: boolean, sync: boolean = false, showErrors: boolean = false): Promise { - this.isOnline = CoreApp.isOnline(); - if (!this.module) { // This can happen if course format changes from single activity to weekly/topics. return; @@ -215,8 +178,6 @@ export class CoreCourseModuleMainActivityComponent extends CoreCourseModuleMainR CoreDomUtils.showErrorModalDefault(error, this.fetchContentDefaultError, true); } finally { this.loaded = true; - this.refreshIcon = CoreConstants.ICON_REFRESH; - this.syncIcon = CoreConstants.ICON_REFRESH; } } @@ -269,8 +230,6 @@ export class CoreCourseModuleMainActivityComponent extends CoreCourseModuleMainR */ ngOnDestroy(): void { super.ngOnDestroy(); - - this.onlineSubscription?.unsubscribe(); this.syncObserver?.off(); } diff --git a/src/core/features/course/classes/main-resource-component.ts b/src/core/features/course/classes/main-resource-component.ts index cc1f72c67..d59380505 100644 --- a/src/core/features/course/classes/main-resource-component.ts +++ b/src/core/features/course/classes/main-resource-component.ts @@ -13,14 +13,10 @@ // limitations under the License. import { CoreConstants } from '@/core/constants'; -import { AddonBlog } from '@addons/blog/services/blog'; -import { AddonBlogMainMenuHandlerService } from '@addons/blog/services/handlers/mainmenu'; import { OnInit, OnDestroy, Input, Output, EventEmitter, Component, Optional, Inject } from '@angular/core'; -import { Params } from '@angular/router'; import { CoreAnyError } from '@classes/errors/error'; import { IonRefresher } from '@ionic/angular'; import { CoreApp } from '@services/app'; -import { CoreNavigator } from '@services/navigator'; import { CoreSites } from '@services/sites'; import { CoreDomUtils } from '@services/utils/dom'; @@ -60,20 +56,11 @@ export class CoreCourseModuleMainResourceComponent implements OnInit, OnDestroy, component?: string; // Component name. componentId?: number; // Component ID. hasOffline = false; // Resources don't have any data to sync. - blog?: boolean; // If blog is available. - // Data for context menu. - externalUrl?: string; // External URL to open in browser. description?: string; // Module description. - refreshIcon = CoreConstants.ICON_LOADING; // Refresh icon, normally spinner or refresh. - prefetchStatusIcon?: string; // Used when calling fillContextMenu. - prefetchStatus?: string; // Used when calling fillContextMenu. - prefetchText?: string; // Used when calling fillContextMenu. - size?: string; // Used when calling fillContextMenu. - downloadTimeReadable?: string; // Last download time in a readable format. Used when calling fillContextMenu. - isDestroyed = false; // Whether the component is destroyed, used when calling fillContextMenu. - contextMenuStatusObserver?: CoreEventObserver; // Observer of package status, used when calling fillContextMenu. - contextFileStatusObserver?: CoreEventObserver; // Observer of file status, used when calling fillContextMenu. + prefetchStatus?: string; + downloadTimeReadable?: string; // Last download time in a readable format. + isDestroyed = false; // Whether the component is destroyed. protected fetchContentDefaultError = 'core.course.errorgetmodule'; // Default error to show when loading contents. protected isCurrentView = false; // Whether the component is in the current view. @@ -84,6 +71,8 @@ export class CoreCourseModuleMainResourceComponent implements OnInit, OnDestroy, protected logger: CoreLogger; protected debouncedUpdateModule?: () => void; // Update the module after a certain time. protected showCompletion = false; // Whether to show completion inside the activity. + protected displayDescription = true; // Wether to show Module description on module page, and not on summary or the contrary. + protected packageStatusObserver?: CoreEventObserver; // Observer of package status. constructor( @Optional() @Inject('') loggerName: string = 'CoreCourseModuleMainResourceComponent', @@ -93,13 +82,12 @@ export class CoreCourseModuleMainResourceComponent implements OnInit, OnDestroy, } /** - * Component being initialized. + * @inheritdoc */ async ngOnInit(): Promise { this.siteId = CoreSites.getCurrentSiteId(); this.description = this.module.description; this.componentId = this.module.id; - this.externalUrl = this.module.url; this.courseId = this.courseId || this.module.course; this.showCompletion = !!CoreSites.getRequiredCurrentSite().isVersionGreaterEqualThan('3.11'); @@ -119,14 +107,22 @@ export class CoreCourseModuleMainResourceComponent implements OnInit, OnDestroy, }, 10000); } - this.blog = await AddonBlog.isPluginEnabled(); + this.packageStatusObserver = CoreEvents.on( + CoreEvents.PACKAGE_STATUS_CHANGED, + (data) => { + if (data.componentId == module.id && data.component == this.component) { + this.getPackageStatus(); + } + }, + this.siteId, + ); } /** * Refresh the data. * * @param refresher Refresher. - * @param done Function to call when done. + * @param done Function to call when done. Never used. * @param showErrors If show errors to the user of hide them. * @return Promise resolved when done. */ @@ -145,7 +141,6 @@ export class CoreCourseModuleMainResourceComponent implements OnInit, OnDestroy, await CoreUtils.ignoreErrors(this.refreshContent(true, showErrors)); refresher?.complete(); - done && done(); } /** @@ -162,22 +157,16 @@ export class CoreCourseModuleMainResourceComponent implements OnInit, OnDestroy, return; } - this.refreshIcon = CoreConstants.ICON_LOADING; + await CoreUtils.ignoreErrors(Promise.all([ + this.invalidateContent(), + this.showCompletion ? CoreCourse.invalidateModule(this.module.id) : undefined, + ])); - try { - await CoreUtils.ignoreErrors(Promise.all([ - this.invalidateContent(), - this.showCompletion ? CoreCourse.invalidateModule(this.module.id) : undefined, - ])); - - if (this.showCompletion) { - this.fetchModule(); - } - - await this.loadContent(true); - } finally { - this.refreshIcon = CoreConstants.ICON_REFRESH; + if (this.showCompletion) { + this.fetchModule(); } + + await this.loadContent(true); } /** @@ -214,6 +203,7 @@ export class CoreCourseModuleMainResourceComponent implements OnInit, OnDestroy, try { await this.fetchContent(refresh); + await this.getPackageStatus(refresh); } catch (error) { if (!refresh && !CoreSites.getCurrentSite()?.isOfflineDisabled() && this.isNotFoundError(error)) { // Module not found, retry without using cache. @@ -223,7 +213,6 @@ export class CoreCourseModuleMainResourceComponent implements OnInit, OnDestroy, CoreDomUtils.showErrorModalDefault(error, this.fetchContentDefaultError, true); } finally { this.loaded = true; - this.refreshIcon = CoreConstants.ICON_REFRESH; } } @@ -238,11 +227,20 @@ export class CoreCourseModuleMainResourceComponent implements OnInit, OnDestroy, } /** - * Fill the context menu options + * Updage package status. + * + * @param refresh If prefetch info has to be refreshed. */ - protected fillContextMenu(refresh: boolean = false): void { - // All data obtained, now fill the context menu. - CoreCourseHelper.fillContextMenu(this, this.module, this.courseId, refresh, this.component); + async getPackageStatus(refresh = false): Promise { + if (!this.module) { + return; + } + + const moduleInfo = + await CoreCourseHelper.getModulePrefetchInfo(this.module, this.courseId, refresh, this.component); + + this.downloadTimeReadable = CoreTextUtils.ucFirst(moduleInfo.downloadTimeReadable); + this.prefetchStatus = moduleInfo.status; } /** @@ -253,48 +251,6 @@ export class CoreCourseModuleMainResourceComponent implements OnInit, OnDestroy, return this.prefetchStatus != CoreConstants.NOT_DOWNLOADABLE && this.prefetchStatus != CoreConstants.NOT_DOWNLOADED; } - /** - * Expand the description. - * - * @deprecated Use openModuleSummary instead. - */ - expandDescription(): void { - this.openModuleSummary(); - } - - /** - * Go to blog posts. - */ - async gotoBlog(): Promise { - const params: Params = { cmId: this.module.id }; - - await CoreNavigator.navigateToSitePath(AddonBlogMainMenuHandlerService.PAGE_NAME, { params }); - } - - /** - * Prefetch the module. - * - * @param done Function to call when done. - */ - prefetch(done?: () => void): void { - CoreCourseHelper.contextMenuPrefetch(this, this.module, this.courseId, done); - } - - /** - * Confirm and remove downloaded files. - * - * @param done Function to call when done. - */ - removeFiles(done?: () => void): void { - if (this.prefetchStatus == CoreConstants.DOWNLOADING) { - CoreDomUtils.showAlertTranslated(undefined, 'core.course.cannotdeletewhiledownloading'); - - return; - } - - CoreCourseHelper.confirmAndRemoveFiles(this.module, this.courseId, done); - } - /** * Get message about an error occurred while downloading files. * @@ -459,7 +415,7 @@ export class CoreCourseModuleMainResourceComponent implements OnInit, OnDestroy, componentProps: { moduleId: this.module.id, module: this.module, - description: this.description, + description: !this.displayDescription ? this.description : '', component: this.component, courseId: this.courseId, hasOffline: this.hasOffline, @@ -493,10 +449,9 @@ export class CoreCourseModuleMainResourceComponent implements OnInit, OnDestroy, */ ngOnDestroy(): void { this.isDestroyed = true; - this.contextMenuStatusObserver?.off(); - this.contextFileStatusObserver?.off(); this.statusObserver?.off(); this.completionObserver?.off(); + this.packageStatusObserver?.off(); } /** diff --git a/src/core/features/course/services/course-helper.ts b/src/core/features/course/services/course-helper.ts index 93c8b0ca6..39e917109 100644 --- a/src/core/features/course/services/course-helper.ts +++ b/src/core/features/course/services/course-helper.ts @@ -493,6 +493,7 @@ export class CoreCourseHelperProvider { * @param courseId Course ID the module belongs to. * @param done Function to call when done. It will close the context menu. * @return Promise resolved when done. + * @deprecated since 4.0 */ async confirmAndRemoveFiles(module: CoreCourseModuleData, courseId: number, done?: () => void): Promise { let modal: CoreIonLoadingElement | undefined; @@ -580,6 +581,7 @@ export class CoreCourseHelperProvider { * @param courseId Course ID the module belongs to. * @param done Function to call when done. It will close the context menu. * @return Promise resolved when done. + * @deprecated since 4.0 */ async contextMenuPrefetch( instance: ComponentWithContextMenu,