diff --git a/.github/workflows/acceptance.yml b/.github/workflows/acceptance.yml index 35b9a772f..c985d05ee 100644 --- a/.github/workflows/acceptance.yml +++ b/.github/workflows/acceptance.yml @@ -157,7 +157,10 @@ jobs: echo $(cd ci/bin; pwd) >> $GITHUB_PATH echo $(cd ci/vendor/bin; pwd) >> $GITHUB_PATH sudo locale-gen en_AU.UTF-8 - echo "NVM_DIR=$HOME/.nvm" >> $GITHUB_ENV + + # Install nvm v0.39.7 as a temporary workaround for issue: + # https://github.com/moodlehq/moodle-plugin-ci/issues/309 + curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash - name: Install Behat Snapshots plugin run: moodle-plugin-ci add-plugin moodlemobile/moodle-local_behatsnapshots diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index df813191c..e5fe0cbd5 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -193,7 +193,10 @@ jobs: echo $(cd ci/bin; pwd) >> $GITHUB_PATH echo $(cd ci/vendor/bin; pwd) >> $GITHUB_PATH sudo locale-gen en_AU.UTF-8 - echo "NVM_DIR=$HOME/.nvm" >> $GITHUB_ENV + + # Install nvm v0.39.7 as a temporary workaround for issue: + # https://github.com/moodlehq/moodle-plugin-ci/issues/309 + curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash - name: Install Behat Snapshots plugin run: moodle-plugin-ci add-plugin moodlemobile/moodle-local_behatsnapshots diff --git a/src/addons/mod/book/pages/contents/contents.html b/src/addons/mod/book/pages/contents/contents.html index d540f7b94..22501f112 100644 --- a/src/addons/mod/book/pages/contents/contents.html +++ b/src/addons/mod/book/pages/contents/contents.html @@ -22,13 +22,6 @@
- - - - -
diff --git a/src/addons/mod/book/pages/contents/contents.ts b/src/addons/mod/book/pages/contents/contents.ts index 39b975103..141d51dc6 100644 --- a/src/addons/mod/book/pages/contents/contents.ts +++ b/src/addons/mod/book/pages/contents/contents.ts @@ -12,15 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { DownloadStatus } from '@/core/constants'; import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core'; import { CoreError } from '@classes/errors/error'; import { CoreSwipeSlidesItemsManager } from '@classes/items-management/swipe-slides-items-manager'; import { CoreSwipeSlidesItemsManagerSource } from '@classes/items-management/swipe-slides-items-manager-source'; import { CoreNavigationBarItem } from '@components/navigation-bar/navigation-bar'; import { CoreSwipeSlidesComponent, CoreSwipeSlidesOptions } from '@components/swipe-slides/swipe-slides'; -import { CoreCourseResourceDownloadResult } from '@features/course/classes/main-resource-component'; -import { CoreCourse } from '@features/course/services/course'; +import { CoreCourse, CoreCourseModuleContentFile } from '@features/course/services/course'; import { CoreCourseModuleData } from '@features/course/services/course-helper'; import { CoreCourseModulePrefetchDelegate } from '@features/course/services/module-prefetch-delegate'; import { CoreTag, CoreTagItem } from '@features/tag/services/tag'; @@ -59,7 +57,6 @@ export class AddonModBookContentsPage implements OnInit, OnDestroy { initialChapterId?: number; component = ADDON_MOD_BOOK_COMPONENT; manager?: CoreSwipeSlidesItemsManager; - warning = ''; displayNavBar = true; navigationItems: CoreNavigationBarItem[] = []; swiperOpts: CoreSwipeSlidesOptions = { @@ -130,24 +127,14 @@ export class AddonModBookContentsPage implements OnInit, OnDestroy { return; } - const { module, book } = await source.loadBookData(); - - const downloadResult = await this.downloadResourceIfNeeded(module, refresh); + const { book } = await source.loadBookData(); this.displayNavBar = book.navstyle != AddonModBookNavStyle.TOC_ONLY; this.title = book.name; - // Get contents. No need to refresh, it has been done in downloadResourceIfNeeded. - await source.loadContents(); + await source.loadContents(refresh); await source.load(); - - if (downloadResult?.failed) { - const error = CoreTextUtils.getErrorMessageFromError(downloadResult.error) || downloadResult.error; - this.warning = Translate.instant('core.errordownloadingsomefiles') + (error ? ' ' + error : ''); - } else { - this.warning = ''; - } } catch (error) { CoreDomUtils.showErrorModalDefault(error, 'core.course.errorgetmodule', true); } finally { @@ -155,62 +142,6 @@ export class AddonModBookContentsPage implements OnInit, OnDestroy { } } - /** - * Download a resource if needed. - * If the download call fails the promise won't be rejected, but the error will be included in the returned object. - * If module.contents cannot be loaded then the Promise will be rejected. - * - * @param module Module to download. - * @param refresh Whether we're refreshing data. - * @returns Promise resolved when done. - */ - protected async downloadResourceIfNeeded( - module: CoreCourseModuleData, - refresh = false, - ): Promise { - - const result: CoreCourseResourceDownloadResult = { - failed: false, - }; - let contentsAlreadyLoaded = false; - - // Get module status to determine if it needs to be downloaded. - const status = await CoreCourseModulePrefetchDelegate.getModuleStatus(module, this.courseId, undefined, refresh); - - if (status !== DownloadStatus.DOWNLOADED) { - // Download content. This function also loads module contents if needed. - try { - await CoreCourseModulePrefetchDelegate.downloadModule(module, this.courseId); - - // If we reach here it means the download process already loaded the contents, no need to do it again. - contentsAlreadyLoaded = true; - } catch (error) { - // Mark download as failed but go on since the main files could have been downloaded. - result.failed = true; - result.error = error; - } - } - - if (!module.contents?.length || (refresh && !contentsAlreadyLoaded)) { - // Try to load the contents. - const ignoreCache = refresh && CoreNetwork.isOnline(); - - try { - await CoreCourse.loadModuleContents(module, undefined, undefined, false, ignoreCache); - } catch (error) { - // Error loading contents. If we ignored cache, try to get the cached value. - if (ignoreCache && !module.contents) { - await CoreCourse.loadModuleContents(module); - } else if (!module.contents) { - // Not able to load contents, throw the error. - throw error; - } - } - } - - return result; - } - /** * Change the current chapter. * @@ -395,18 +326,48 @@ class AddonModBookSlidesItemsManagerSource extends CoreSwipeSlidesItemsManagerSo /** * Load module contents. + * + * @param refresh Whether we're refreshing data. */ - async loadContents(): Promise { + async loadContents(refresh = false): Promise { if (!this.module) { return; } - const contents = await CoreCourse.getModuleContents(this.module, this.COURSE_ID); + const contents = await this.getModuleContents(refresh); this.contentsMap = AddonModBook.getContentsMap(contents); this.chapters = AddonModBook.getTocList(contents); } + /** + * Get module contents. + * + * @param refresh Whether we're refreshing data. + * @returns Module contents. + */ + protected async getModuleContents(refresh = false): Promise { + if (!this.module) { + return []; + } + + const ignoreCache = refresh && CoreNetwork.isOnline(); + + try { + return await CoreCourse.getModuleContents(this.module, this.COURSE_ID, undefined, false, ignoreCache); + } catch (error) { + // Error loading contents. If we ignored cache, try to get the cached value. + if (ignoreCache && !this.module.contents) { + return await CoreCourse.getModuleContents(this.module); + } else if (!this.module.contents) { + // Not able to load contents, throw the error. + throw error; + } + + return this.module.contents; + } + } + /** * @inheritdoc */ 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 2f82a39e6..d6978007d 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 @@ -12,13 +12,6 @@ - - - - -
diff --git a/src/addons/mod/page/components/index/index.ts b/src/addons/mod/page/components/index/index.ts index fcef8de3f..5e78527f1 100644 --- a/src/addons/mod/page/components/index/index.ts +++ b/src/addons/mod/page/components/index/index.ts @@ -15,7 +15,6 @@ import { Component, OnInit, Optional } from '@angular/core'; import { CoreCourseModuleMainResourceComponent } from '@features/course/classes/main-resource-component'; import { CoreCourseContentsPage } from '@features/course/pages/contents/contents'; -import { CoreCourse } from '@features/course/services/course'; import { CoreTextUtils } from '@services/utils/text'; import { CoreUtils } from '@services/utils/utils'; import { AddonModPagePage, AddonModPage } from '../../services/page'; @@ -38,7 +37,6 @@ export class AddonModPageIndexComponent extends CoreCourseModuleMainResourceComp displayTimemodified = true; timemodified?: number; page?: AddonModPagePage; - warning?: string; protected fetchContentDefaultError = 'addon.mod_page.errorwhileloadingthepage'; @@ -68,19 +66,12 @@ export class AddonModPageIndexComponent extends CoreCourseModuleMainResourceComp * @inheritdoc */ protected async fetchContent(refresh?: boolean): Promise { - // 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); - - const results = await Promise.all([ + const [contents] = await Promise.all([ + this.getModuleContents(refresh), this.loadPageData(), - AddonModPageHelper.getPageHtml(contents, this.module.id), ]); - this.contents = results[1]; - this.warning = downloadResult?.failed ? this.getErrorDownloadingSomeFilesMessage(downloadResult.error!) : ''; + this.contents = await AddonModPageHelper.getPageHtml(contents, this.module.id); } /** diff --git a/src/core/features/course/classes/main-resource-component.ts b/src/core/features/course/classes/main-resource-component.ts index 40a2e7cda..6434c503b 100644 --- a/src/core/features/course/classes/main-resource-component.ts +++ b/src/core/features/course/classes/main-resource-component.ts @@ -26,7 +26,7 @@ import { CoreEventObserver, CoreEvents } from '@singletons/events'; import { CoreLogger } from '@singletons/logger'; import { CoreCourseModuleSummaryResult } from '../components/module-summary/module-summary'; import { CoreCourseContentsPage } from '../pages/contents/contents'; -import { CoreCourse } from '../services/course'; +import { CoreCourse, CoreCourseModuleContentFile } from '../services/course'; import { CoreCourseHelper, CoreCourseModuleData } from '../services/course-helper'; import { CoreCourseModuleDelegate, CoreCourseModuleMainComponent } from '../services/module-delegate'; import { CoreCourseModulePrefetchDelegate } from '../services/module-prefetch-delegate'; @@ -364,24 +364,36 @@ export class CoreCourseModuleMainResourceComponent implements OnInit, OnDestroy, if (!this.module.contents?.length || (refresh && !contentsAlreadyLoaded)) { // Try to load the contents. - const ignoreCache = refresh && CoreNetwork.isOnline(); - - try { - await CoreCourse.loadModuleContents(this.module, undefined, undefined, false, ignoreCache); - } catch (error) { - // Error loading contents. If we ignored cache, try to get the cached value. - if (ignoreCache && !this.module.contents) { - await CoreCourse.loadModuleContents(this.module); - } else if (!this.module.contents) { - // Not able to load contents, throw the error. - throw error; - } - } + await this.getModuleContents(refresh); } return result; } + /** + * Get module contents. + * + * @param refresh Whether we're refreshing data. + * @returns Module contents. + */ + protected async getModuleContents(refresh?: boolean): Promise { + const ignoreCache = refresh && CoreNetwork.isOnline(); + + try { + return await CoreCourse.getModuleContents(this.module, undefined, undefined, false, ignoreCache); + } catch (error) { + // Error loading contents. If we ignored cache, try to get the cached value. + if (ignoreCache && !this.module.contents) { + return await CoreCourse.getModuleContents(this.module); + } else if (!this.module.contents) { + // Not able to load contents, throw the error. + throw error; + } + + return this.module.contents; + } + } + /** * The completion of the modules has changed. *