MOBILE-3855 course: Fix length of undefined error in hidden modules
parent
67c4a3e928
commit
a26bbe5cfb
|
@ -133,8 +133,11 @@ export class AddonModBookIndexComponent extends CoreCourseModuleMainResourceComp
|
||||||
|
|
||||||
await this.loadBookData();
|
await this.loadBookData();
|
||||||
|
|
||||||
this.contentsMap = AddonModBook.getContentsMap(this.module.contents);
|
// Get contents. No need to refresh, it has been done in downloadResourceIfNeeded.
|
||||||
this.chapters = AddonModBook.getTocList(this.module.contents);
|
const contents = await CoreCourse.getModuleContents(this.module, this.courseId);
|
||||||
|
|
||||||
|
this.contentsMap = AddonModBook.getContentsMap(contents);
|
||||||
|
this.chapters = AddonModBook.getTocList(contents);
|
||||||
|
|
||||||
if (typeof this.currentChapter == 'undefined' && typeof this.initialChapterId != 'undefined' && this.chapters) {
|
if (typeof this.currentChapter == 'undefined' && typeof this.initialChapterId != 'undefined' && this.chapters) {
|
||||||
// Initial chapter set. Validate that the chapter exists.
|
// Initial chapter set. Validate that the chapter exists.
|
||||||
|
|
|
@ -34,8 +34,8 @@
|
||||||
contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId">
|
contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId">
|
||||||
</core-course-module-description>
|
</core-course-module-description>
|
||||||
|
|
||||||
<ion-list *ngIf="contents && (contents!.files.length + contents!.folders.length > 0)">
|
<ion-list *ngIf="contents && (contents.files.length + contents.folders.length > 0)">
|
||||||
<ng-container *ngFor="let folder of contents!.folders">
|
<ng-container *ngFor="let folder of contents.folders">
|
||||||
<ion-item class="item-file" (click)="openFolder(folder)" detail="true" button>
|
<ion-item class="item-file" (click)="openFolder(folder)" detail="true" button>
|
||||||
<ion-icon name="fas-folder" slot="start" [attr.aria-label]="'core.folder' | translate"></ion-icon>
|
<ion-icon name="fas-folder" slot="start" [attr.aria-label]="'core.folder' | translate"></ion-icon>
|
||||||
<ion-label>
|
<ion-label>
|
||||||
|
@ -43,12 +43,12 @@
|
||||||
</ion-label>
|
</ion-label>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<ng-container *ngFor="let file of contents!.files">
|
<ng-container *ngFor="let file of contents.files">
|
||||||
<core-file [file]="file" [component]="component" [componentId]="componentId"></core-file>
|
<core-file [file]="file" [component]="component" [componentId]="componentId"></core-file>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</ion-list>
|
</ion-list>
|
||||||
|
|
||||||
<core-empty-box *ngIf="!contents || (contents!.files.length + contents!.folders.length == 0)" icon="far-folder-open"
|
<core-empty-box *ngIf="!contents || (contents.files.length + contents.folders.length == 0)" icon="far-folder-open"
|
||||||
[message]=" 'addon.mod_folder.emptyfilelist' | translate"></core-empty-box>
|
[message]=" 'addon.mod_folder.emptyfilelist' | translate"></core-empty-box>
|
||||||
|
|
||||||
</core-loading>
|
</core-loading>
|
||||||
|
|
|
@ -95,12 +95,13 @@ export class AddonModFolderIndexComponent extends CoreCourseModuleMainResourceCo
|
||||||
protected async fetchContent(refresh = false): Promise<void> {
|
protected async fetchContent(refresh = false): Promise<void> {
|
||||||
try {
|
try {
|
||||||
this.folderInstance = await AddonModFolder.getFolder(this.courseId, this.module.id);
|
this.folderInstance = await AddonModFolder.getFolder(this.courseId, this.module.id);
|
||||||
await CoreCourse.loadModuleContents(this.module, this.courseId, undefined, false, refresh);
|
|
||||||
|
const contents = await CoreCourse.getModuleContents(this.module, this.courseId, 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.description = this.folderInstance ? this.folderInstance.intro : this.module.description;
|
||||||
this.contents = AddonModFolderHelper.formatContents(this.module.contents);
|
this.contents = AddonModFolderHelper.formatContents(contents);
|
||||||
} finally {
|
} finally {
|
||||||
this.fillContextMenu(refresh);
|
this.fillContextMenu(refresh);
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,7 +85,10 @@ export class AddonModImscpIndexComponent extends CoreCourseModuleMainResourceCom
|
||||||
this.description = imscp.intro;
|
this.description = imscp.intro;
|
||||||
this.dataRetrieved.emit(imscp);
|
this.dataRetrieved.emit(imscp);
|
||||||
|
|
||||||
this.items = AddonModImscp.createItemList(this.module.contents);
|
// Get contents. No need to refresh, it has been done in downloadResourceIfNeeded.
|
||||||
|
const contents = await CoreCourse.getModuleContents(this.module, this.courseId);
|
||||||
|
|
||||||
|
this.items = AddonModImscp.createItemList(contents);
|
||||||
|
|
||||||
if (this.items.length && typeof this.currentItem == 'undefined') {
|
if (this.items.length && typeof this.currentItem == 'undefined') {
|
||||||
this.currentItem = this.items[0].href;
|
this.currentItem = this.items[0].href;
|
||||||
|
|
|
@ -229,8 +229,10 @@ export class AddonModImscpProvider {
|
||||||
* @return Promise resolved with the item src.
|
* @return Promise resolved with the item src.
|
||||||
*/
|
*/
|
||||||
async getIframeSrc(module: CoreCourseModule, itemHref?: string): Promise<string> {
|
async getIframeSrc(module: CoreCourseModule, itemHref?: string): Promise<string> {
|
||||||
|
const contents = await CoreCourse.getModuleContents(module);
|
||||||
|
|
||||||
if (!itemHref) {
|
if (!itemHref) {
|
||||||
const toc = this.getToc(module.contents);
|
const toc = this.getToc(contents);
|
||||||
if (!toc.length) {
|
if (!toc.length) {
|
||||||
throw new CoreError('Empty TOC');
|
throw new CoreError('Empty TOC');
|
||||||
}
|
}
|
||||||
|
@ -246,7 +248,7 @@ export class AddonModImscpProvider {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// Error getting directory, there was an error downloading or we're in browser. Return online URL if connected.
|
// Error getting directory, there was an error downloading or we're in browser. Return online URL if connected.
|
||||||
if (CoreApp.isOnline()) {
|
if (CoreApp.isOnline()) {
|
||||||
const indexUrl = this.getFileUrlFromContents(module.contents, itemHref);
|
const indexUrl = this.getFileUrlFromContents(contents, itemHref);
|
||||||
|
|
||||||
if (indexUrl) {
|
if (indexUrl) {
|
||||||
const site = await CoreSites.getSite(siteId);
|
const site = await CoreSites.getSite(siteId);
|
||||||
|
|
|
@ -81,9 +81,12 @@ export class AddonModPageIndexComponent extends CoreCourseModuleMainResourceComp
|
||||||
// Download the resource if it needs to be downloaded.
|
// Download the resource if it needs to be downloaded.
|
||||||
const downloadResult = await this.downloadResourceIfNeeded(refresh);
|
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, this.courseId);
|
||||||
|
|
||||||
const results = await Promise.all([
|
const results = await Promise.all([
|
||||||
this.loadPageData(),
|
this.loadPageData(),
|
||||||
AddonModPageHelper.getPageHtml(this.module.contents, this.module.id),
|
AddonModPageHelper.getPageHtml(contents, this.module.id),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
this.contents = results[1];
|
this.contents = results[1];
|
||||||
|
|
|
@ -101,9 +101,9 @@ export class AddonModResourceIndexComponent extends CoreCourseModuleMainResource
|
||||||
*/
|
*/
|
||||||
protected async fetchContent(refresh?: boolean): Promise<void> {
|
protected async fetchContent(refresh?: boolean): Promise<void> {
|
||||||
// Load module contents if needed. Passing refresh is needed to force reloading contents.
|
// Load module contents if needed. Passing refresh is needed to force reloading contents.
|
||||||
await CoreCourse.loadModuleContents(this.module, this.courseId, undefined, false, refresh);
|
const contents = await CoreCourse.getModuleContents(this.module, this.courseId, undefined, false, refresh);
|
||||||
|
|
||||||
if (!this.module.contents || !this.module.contents.length) {
|
if (!contents.length) {
|
||||||
throw new CoreError(Translate.instant('core.filenotfound'));
|
throw new CoreError(Translate.instant('core.filenotfound'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,10 +155,10 @@ export class AddonModResourceIndexComponent extends CoreCourseModuleMainResource
|
||||||
this.warning = '';
|
this.warning = '';
|
||||||
|
|
||||||
if (this.isIOS) {
|
if (this.isIOS) {
|
||||||
this.shouldOpenInBrowser = CoreFileHelper.shouldOpenInBrowser(this.module.contents[0]);
|
this.shouldOpenInBrowser = CoreFileHelper.shouldOpenInBrowser(contents[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
const mimetype = await CoreUtils.getMimeTypeFromUrl(CoreFileHelper.getFileUrl(this.module.contents[0]));
|
const mimetype = await CoreUtils.getMimeTypeFromUrl(CoreFileHelper.getFileUrl(contents[0]));
|
||||||
|
|
||||||
this.isStreamedFile = CoreMimetypeUtils.isStreamedMimetype(mimetype);
|
this.isStreamedFile = CoreMimetypeUtils.isStreamedMimetype(mimetype);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ import { CoreDomUtils } from '@services/utils/dom';
|
||||||
import { CoreMimetypeUtils } from '@services/utils/mimetype';
|
import { CoreMimetypeUtils } from '@services/utils/mimetype';
|
||||||
import { CoreTextUtils } from '@services/utils/text';
|
import { CoreTextUtils } from '@services/utils/text';
|
||||||
import { CoreUtilsOpenFileOptions } from '@services/utils/utils';
|
import { CoreUtilsOpenFileOptions } from '@services/utils/utils';
|
||||||
import { makeSingleton } from '@singletons';
|
import { makeSingleton, Translate } from '@singletons';
|
||||||
import { AddonModResource, AddonModResourceProvider } from './resource';
|
import { AddonModResource, AddonModResourceProvider } from './resource';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -43,15 +43,17 @@ export class AddonModResourceHelperProvider {
|
||||||
* @return Promise resolved with the HTML.
|
* @return Promise resolved with the HTML.
|
||||||
*/
|
*/
|
||||||
async getEmbeddedHtml(module: CoreCourseWSModule, courseId: number): Promise<string> {
|
async getEmbeddedHtml(module: CoreCourseWSModule, courseId: number): Promise<string> {
|
||||||
|
const contents = await CoreCourse.getModuleContents(module, courseId);
|
||||||
|
|
||||||
const result = await CoreCourseHelper.downloadModuleWithMainFileIfNeeded(
|
const result = await CoreCourseHelper.downloadModuleWithMainFileIfNeeded(
|
||||||
module,
|
module,
|
||||||
courseId,
|
courseId,
|
||||||
AddonModResourceProvider.COMPONENT,
|
AddonModResourceProvider.COMPONENT,
|
||||||
module.id,
|
module.id,
|
||||||
module.contents,
|
contents,
|
||||||
);
|
);
|
||||||
|
|
||||||
return CoreMimetypeUtils.getEmbeddedHtml(module.contents[0], result.path);
|
return CoreMimetypeUtils.getEmbeddedHtml(contents[0], result.path);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -61,7 +63,7 @@ export class AddonModResourceHelperProvider {
|
||||||
* @return Promise resolved with the iframe src.
|
* @return Promise resolved with the iframe src.
|
||||||
*/
|
*/
|
||||||
async getIframeSrc(module: CoreCourseWSModule): Promise<string> {
|
async getIframeSrc(module: CoreCourseWSModule): Promise<string> {
|
||||||
if (!module.contents.length) {
|
if (!module.contents?.length) {
|
||||||
throw new CoreError('No contents available in module');
|
throw new CoreError('No contents available in module');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,15 +100,19 @@ export class AddonModResourceHelperProvider {
|
||||||
isDisplayedEmbedded(module: CoreCourseWSModule, display: number): boolean {
|
isDisplayedEmbedded(module: CoreCourseWSModule, display: number): boolean {
|
||||||
const currentSite = CoreSites.getCurrentSite();
|
const currentSite = CoreSites.getCurrentSite();
|
||||||
|
|
||||||
if ((!module.contents.length && !module.contentsinfo) ||
|
if (!CoreFile.isAvailable() ||
|
||||||
!CoreFile.isAvailable() ||
|
(currentSite && !currentSite.isVersionGreaterEqualThan('3.7') && this.isNextcloudFile(module))) {
|
||||||
(currentSite && !currentSite.isVersionGreaterEqualThan('3.7') && this.isNextcloudFile(module))) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ext = module.contentsinfo
|
let ext: string | undefined;
|
||||||
? CoreMimetypeUtils.getExtension(module.contentsinfo.mimetypes[0])
|
if (module.contentsinfo) {
|
||||||
: CoreMimetypeUtils.getFileExtension(module.contents[0].filename);
|
ext = CoreMimetypeUtils.getExtension(module.contentsinfo.mimetypes[0]);
|
||||||
|
} else if (module.contents?.length) {
|
||||||
|
ext = CoreMimetypeUtils.getFileExtension(module.contents[0].filename);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return (display == CoreConstants.RESOURCELIB_DISPLAY_EMBED || display == CoreConstants.RESOURCELIB_DISPLAY_AUTO) &&
|
return (display == CoreConstants.RESOURCELIB_DISPLAY_EMBED || display == CoreConstants.RESOURCELIB_DISPLAY_AUTO) &&
|
||||||
CoreMimetypeUtils.canBeEmbedded(ext);
|
CoreMimetypeUtils.canBeEmbedded(ext);
|
||||||
|
@ -144,10 +150,15 @@ export class AddonModResourceHelperProvider {
|
||||||
* @param siteId Site ID. If not defined, current site.
|
* @param siteId Site ID. If not defined, current site.
|
||||||
* @return Promise resolved with boolean: whether main file is downloadable.
|
* @return Promise resolved with boolean: whether main file is downloadable.
|
||||||
*/
|
*/
|
||||||
isMainFileDownloadable(module: CoreCourseWSModule, siteId?: string): Promise<boolean> {
|
async isMainFileDownloadable(module: CoreCourseWSModule, siteId?: string): Promise<boolean> {
|
||||||
|
const contents = await CoreCourse.getModuleContents(module);
|
||||||
|
if (!contents.length) {
|
||||||
|
throw new CoreError(Translate.instant('core.filenotfound'));
|
||||||
|
}
|
||||||
|
|
||||||
siteId = siteId || CoreSites.getCurrentSiteId();
|
siteId = siteId || CoreSites.getCurrentSiteId();
|
||||||
|
|
||||||
const mainFile = module.contents[0];
|
const mainFile = contents[0];
|
||||||
const timemodified = CoreFileHelper.getFileTimemodified(mainFile);
|
const timemodified = CoreFileHelper.getFileTimemodified(mainFile);
|
||||||
|
|
||||||
return CoreFilepool.isFileDownloadable(siteId, mainFile.fileurl, timemodified);
|
return CoreFilepool.isFileDownloadable(siteId, mainFile.fileurl, timemodified);
|
||||||
|
|
|
@ -95,11 +95,19 @@ export class AddonModUrlIndexComponent extends CoreCourseModuleMainResourceCompo
|
||||||
this.displayDescription = typeof unserialized.printintro == 'undefined' || !!unserialized.printintro;
|
this.displayDescription = typeof unserialized.printintro == 'undefined' || !!unserialized.printintro;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to load module contents, it's needed to get the URL with parameters.
|
// Try to get module contents, it's needed to get the URL with parameters.
|
||||||
await CoreCourse.loadModuleContents(this.module, this.courseId, undefined, false, refresh, undefined, 'url');
|
const contents = await CoreCourse.getModuleContents(
|
||||||
|
this.module,
|
||||||
|
this.courseId,
|
||||||
|
undefined,
|
||||||
|
false,
|
||||||
|
refresh,
|
||||||
|
undefined,
|
||||||
|
'url',
|
||||||
|
);
|
||||||
|
|
||||||
// Always use the URL from the module because it already includes the parameters.
|
// Always use the URL from the module because it already includes the parameters.
|
||||||
this.url = this.module.contents[0] && this.module.contents[0].fileurl ? this.module.contents[0].fileurl : undefined;
|
this.url = contents[0] && contents[0].fileurl ? contents[0].fileurl : undefined;
|
||||||
|
|
||||||
await this.calculateDisplayOptions(url);
|
await this.calculateDisplayOptions(url);
|
||||||
|
|
||||||
|
@ -112,12 +120,12 @@ export class AddonModUrlIndexComponent extends CoreCourseModuleMainResourceCompo
|
||||||
this.description = mod.description;
|
this.description = mod.description;
|
||||||
this.dataRetrieved.emit(mod);
|
this.dataRetrieved.emit(mod);
|
||||||
|
|
||||||
if (!mod.contents.length) {
|
if (!mod.contents?.length) {
|
||||||
// If the data was cached maybe we don't have contents. Reject.
|
// If the data was cached maybe we don't have contents. Reject.
|
||||||
throw new CoreError('No contents found in module.');
|
throw new CoreError('No contents found in module.');
|
||||||
}
|
}
|
||||||
|
|
||||||
this.url = mod.contents && mod.contents[0] && mod.contents[0].fileurl ? mod.contents[0].fileurl : undefined;
|
this.url = mod.contents[0].fileurl ? mod.contents[0].fileurl : undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -77,7 +77,8 @@ export class AddonModUrlModuleHandlerService implements CoreCourseModuleHandler
|
||||||
// Ignore errors.
|
// Ignore errors.
|
||||||
}
|
}
|
||||||
|
|
||||||
AddonModUrlHelper.open(module.contents[0].fileurl);
|
const contents = await CoreCourse.getModuleContents(module, courseId);
|
||||||
|
AddonModUrlHelper.open(contents[0].fileurl);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handlerData: CoreCourseModuleHandlerData = {
|
const handlerData: CoreCourseModuleHandlerData = {
|
||||||
|
@ -141,9 +142,9 @@ export class AddonModUrlModuleHandlerService implements CoreCourseModuleHandler
|
||||||
*/
|
*/
|
||||||
protected async hideLinkButton(module: CoreCourseAnyModuleData, courseId: number): Promise<boolean> {
|
protected async hideLinkButton(module: CoreCourseAnyModuleData, courseId: number): Promise<boolean> {
|
||||||
try {
|
try {
|
||||||
await CoreCourse.loadModuleContents(module, courseId, undefined, false, false, undefined, this.modName);
|
const contents = await CoreCourse.getModuleContents(module, courseId, undefined, false, false, undefined, this.modName);
|
||||||
|
|
||||||
return !(module.contents && module.contents[0] && module.contents[0].fileurl);
|
return !(contents[0] && contents[0].fileurl);
|
||||||
} catch {
|
} catch {
|
||||||
// Module contents could not be loaded, most probably device is offline.
|
// Module contents could not be loaded, most probably device is offline.
|
||||||
return true;
|
return true;
|
||||||
|
@ -166,11 +167,10 @@ export class AddonModUrlModuleHandlerService implements CoreCourseModuleHandler
|
||||||
*/
|
*/
|
||||||
protected async shouldOpenLink(module: CoreCourseModule, courseId: number): Promise<boolean> {
|
protected async shouldOpenLink(module: CoreCourseModule, courseId: number): Promise<boolean> {
|
||||||
try {
|
try {
|
||||||
// First of all, make sure module contents are loaded.
|
const contents = await CoreCourse.getModuleContents(module, courseId, undefined, false, false, undefined, this.modName);
|
||||||
await CoreCourse.loadModuleContents(module, courseId, undefined, false, false, undefined, this.modName);
|
|
||||||
|
|
||||||
// Check if the URL can be handled by the app. If so, always open it directly.
|
// Check if the URL can be handled by the app. If so, always open it directly.
|
||||||
const canHandle = await CoreContentLinksHelper.canHandleLink(module.contents[0].fileurl, courseId, undefined, true);
|
const canHandle = await CoreContentLinksHelper.canHandleLink(contents[0].fileurl, courseId, undefined, true);
|
||||||
|
|
||||||
if (canHandle) {
|
if (canHandle) {
|
||||||
// URL handled by the app, open it directly.
|
// URL handled by the app, open it directly.
|
||||||
|
|
|
@ -390,7 +390,7 @@ export class CoreCourseModuleMainResourceComponent implements OnInit, OnDestroy,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.module.contents.length || (refresh && !contentsAlreadyLoaded)) {
|
if (!this.module.contents?.length || (refresh && !contentsAlreadyLoaded)) {
|
||||||
// Try to load the contents.
|
// Try to load the contents.
|
||||||
const ignoreCache = refresh && CoreApp.isOnline();
|
const ignoreCache = refresh && CoreApp.isOnline();
|
||||||
|
|
||||||
|
|
|
@ -730,13 +730,11 @@ export class CoreCourseHelperProvider {
|
||||||
siteId = siteId || CoreSites.getCurrentSiteId();
|
siteId = siteId || CoreSites.getCurrentSiteId();
|
||||||
|
|
||||||
if (!files || !files.length) {
|
if (!files || !files.length) {
|
||||||
// Make sure that module contents are loaded.
|
// Try to use module contents.
|
||||||
await CoreCourse.loadModuleContents(module, courseId);
|
files = await CoreCourse.getModuleContents(module, courseId);
|
||||||
|
|
||||||
files = module.contents;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!files || !files.length) {
|
if (!files.length) {
|
||||||
throw new CoreError(Translate.instant('core.filenotfound'));
|
throw new CoreError(Translate.instant('core.filenotfound'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1033,7 +1031,7 @@ export class CoreCourseHelperProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
// There's no prefetch handler for the module, just download the files.
|
// There's no prefetch handler for the module, just download the files.
|
||||||
files = files || module.contents;
|
files = files || module.contents || [];
|
||||||
|
|
||||||
await CoreFilepool.downloadOrPrefetchFiles(siteId, files, false, false, component, componentId);
|
await CoreFilepool.downloadOrPrefetchFiles(siteId, files, false, false, component, componentId);
|
||||||
}
|
}
|
||||||
|
|
|
@ -885,9 +885,47 @@ export class CoreCourseProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
const mod = await this.getModule(module.id, courseId, sectionId, preferCache, ignoreCache, siteId, modName);
|
const mod = await this.getModule(module.id, courseId, sectionId, preferCache, ignoreCache, siteId, modName);
|
||||||
|
|
||||||
|
if (!mod.contents) {
|
||||||
|
throw new CoreError(Translate.instant('core.course.modulenotfound'));
|
||||||
|
}
|
||||||
|
|
||||||
module.contents = mod.contents;
|
module.contents = mod.contents;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get module contents. If not present, this function will try to load them into module.contents.
|
||||||
|
* It will throw an error if contents cannot be loaded.
|
||||||
|
*
|
||||||
|
* @param module Module to get its contents.
|
||||||
|
* @param courseId The course ID. Recommended to speed up the process and minimize data usage.
|
||||||
|
* @param sectionId The section ID.
|
||||||
|
* @param preferCache True if shouldn't call WS if data is cached, false otherwise.
|
||||||
|
* @param ignoreCache True if it should ignore cached data (it will always fail in offline or server down).
|
||||||
|
* @param siteId Site ID. If not defined, current site.
|
||||||
|
* @param modName If set, the app will retrieve all modules of this type with a single WS call. This reduces the
|
||||||
|
* number of WS calls, but it isn't recommended for modules that can return a lot of contents.
|
||||||
|
* @return Promise resolved when loaded.
|
||||||
|
*/
|
||||||
|
async getModuleContents(
|
||||||
|
module: CoreCourseAnyModuleData,
|
||||||
|
courseId?: number,
|
||||||
|
sectionId?: number,
|
||||||
|
preferCache?: boolean,
|
||||||
|
ignoreCache?: boolean,
|
||||||
|
siteId?: string,
|
||||||
|
modName?: string,
|
||||||
|
): Promise<CoreCourseModuleContentFile[]> {
|
||||||
|
// Make sure contents are loaded.
|
||||||
|
await this.loadModuleContents(module, courseId, sectionId, preferCache, ignoreCache, siteId, modName);
|
||||||
|
|
||||||
|
if (!module.contents) {
|
||||||
|
throw new CoreError(Translate.instant('core.course.modulenotfound'));
|
||||||
|
}
|
||||||
|
|
||||||
|
return module.contents;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Report a course and section as being viewed.
|
* Report a course and section as being viewed.
|
||||||
*
|
*
|
||||||
|
@ -1450,7 +1488,7 @@ export type CoreCourseWSModule = {
|
||||||
noviewlink?: boolean; // Whether the module has no view page.
|
noviewlink?: boolean; // Whether the module has no view page.
|
||||||
completion?: number; // Type of completion tracking: 0 means none, 1 manual, 2 automatic.
|
completion?: number; // Type of completion tracking: 0 means none, 1 manual, 2 automatic.
|
||||||
completiondata?: CoreCourseModuleWSCompletionData; // Module completion data.
|
completiondata?: CoreCourseModuleWSCompletionData; // Module completion data.
|
||||||
contents: CoreCourseModuleContentFile[];
|
contents?: CoreCourseModuleContentFile[];
|
||||||
dates?: {
|
dates?: {
|
||||||
label: string;
|
label: string;
|
||||||
timestamp: number;
|
timestamp: number;
|
||||||
|
@ -1589,5 +1627,5 @@ type CoreCompletionUpdateActivityCompletionStatusManuallyWSParams = {
|
||||||
* Any of the possible module WS data.
|
* Any of the possible module WS data.
|
||||||
*/
|
*/
|
||||||
export type CoreCourseAnyModuleData = CoreCourseWSModule | CoreCourseModuleBasicInfo & {
|
export type CoreCourseAnyModuleData = CoreCourseWSModule | CoreCourseModuleBasicInfo & {
|
||||||
contents?: CoreCourseModuleContentFile[]; // Calculated in the app in loadModuleContents.
|
contents?: CoreCourseModuleContentFile[]; // If needed, calculated in the app in loadModuleContents.
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue