diff --git a/src/addon/mod/resource/providers/helper.ts b/src/addon/mod/resource/providers/helper.ts index ad461c6a5..2d357c615 100644 --- a/src/addon/mod/resource/providers/helper.ts +++ b/src/addon/mod/resource/providers/helper.ts @@ -113,12 +113,17 @@ export class AddonModResourceHelperProvider { * @return {boolean} Whether the resource should be displayed embeded. */ isDisplayedEmbedded(module: any, display: number): boolean { - if (!module.contents.length || !this.fileProvider.isAvailable() || + if ((!module.contents.length && !module.contentsinfo) || !this.fileProvider.isAvailable() || (!this.sitesProvider.getCurrentSite().isVersionGreaterEqualThan('3.7') && this.isNextcloudFile(module))) { - return false; } - const ext = this.mimetypeUtils.getFileExtension(module.contents[0].filename); + let ext; + + if (module.contentsinfo) { + ext = this.mimetypeUtils.getExtension(module.contentsinfo.mimetypes[0]); + } else { + ext = this.mimetypeUtils.getFileExtension(module.contents[0].filename); + } return (display == this.DISPLAY_EMBED || display == this.DISPLAY_AUTO) && this.mimetypeUtils.canBeEmbedded(ext); } @@ -130,12 +135,18 @@ export class AddonModResourceHelperProvider { * @return {boolean} Whether the resource should be displayed in an iframe. */ isDisplayedInIframe(module: any): boolean { - if (!module.contents.length || !this.fileProvider.isAvailable()) { + if ((!module.contents.length && !module.contentsinfo) || !this.fileProvider.isAvailable()) { return false; } - const ext = this.mimetypeUtils.getFileExtension(module.contents[0].filename), + let mimetype; + + if (module.contentsinfo) { + mimetype = module.contentsinfo.mimetypes[0]; + } else { + const ext = this.mimetypeUtils.getFileExtension(module.contents[0].filename); mimetype = this.mimetypeUtils.getMimeType(ext); + } return mimetype == 'text/html'; } @@ -147,6 +158,10 @@ export class AddonModResourceHelperProvider { * @return {boolean} Whether it's a Nextcloud file. */ isNextcloudFile(module: any): boolean { + if (module.contentsinfo) { + return module.contentsinfo.repositorytype == 'nextcloud'; + } + return module.contents && module.contents[0] && module.contents[0].repositorytype == 'nextcloud'; } diff --git a/src/addon/mod/resource/providers/module-handler.ts b/src/addon/mod/resource/providers/module-handler.ts index 5dc520d7b..905f192e5 100644 --- a/src/addon/mod/resource/providers/module-handler.ts +++ b/src/addon/mod/resource/providers/module-handler.ts @@ -121,8 +121,16 @@ export class AddonModResourceModuleHandler implements CoreCourseModuleHandler { * @return {Promise} Resolved when done. */ protected hideOpenButton(module: any, courseId: number): Promise { - return this.courseProvider.loadModuleContents(module, courseId, undefined, false, false, undefined, this.modName) - .then(() => { + let promise; + + if (module.contentsinfo) { + // No need to load contents. + promise = Promise.resolve(); + } else { + promise = this.courseProvider.loadModuleContents(module, courseId, undefined, false, false, undefined, this.modName); + } + + return promise.then(() => { return this.prefetchDelegate.getModuleStatus(module, courseId).then((status) => { return status !== CoreConstants.DOWNLOADED || this.resourceHelper.isDisplayedInIframe(module); }); @@ -141,7 +149,7 @@ export class AddonModResourceModuleHandler implements CoreCourseModuleHandler { let infoFiles = [], options: any = {}; - // Check if the button needs to be shown or not. This also loads the module contents. + // Check if the button needs to be shown or not. promises.push(this.hideOpenButton(module, courseId).then((hideOpenButton) => { handlerData.buttons[0].hidden = hideOpenButton; })); @@ -164,7 +172,13 @@ export class AddonModResourceModuleHandler implements CoreCourseModuleHandler { }, extra = []; - if (files && files.length) { + if (module.contentsinfo) { + // No need to use the list of files. + const mimetype = module.contentsinfo.mimetypes[0]; + resourceData.icon = this.mimetypeUtils.getMimetypeIcon(mimetype); + resourceData.extra = this.textUtils.cleanTags(module.afterlink); + + } else if (files && files.length) { const file = files[0]; resourceData.icon = this.mimetypeUtils.getFileIcon(file.filename); @@ -178,11 +192,12 @@ export class AddonModResourceModuleHandler implements CoreCourseModuleHandler { return result + file.filesize; }, 0); } + extra.push(this.textUtils.bytesToSize(size, 1)); } if (options.showtype) { - // We should take it from options.filedetails.size if avalaible ∫but it's already translated. + // We should take it from options.filedetails.size if avalaible but it's already translated. extra.push(this.mimetypeUtils.getMimetypeDescription(file)); } @@ -203,12 +218,15 @@ export class AddonModResourceModuleHandler implements CoreCourseModuleHandler { {$a: this.timeUtils.userDate(file.timecreated * 1000, 'core.strftimedatetimeshort') })); } } - } - if (resourceData.icon == '') { + if (resourceData.icon == '') { + resourceData.icon = this.courseProvider.getModuleIconSrc(this.modName, module.modicon); + } + resourceData.extra += extra.join(' '); + } else { + // No files, just set the icon. resourceData.icon = this.courseProvider.getModuleIconSrc(this.modName, module.modicon); } - resourceData.extra += extra.join(' '); return resourceData; }); diff --git a/src/addon/mod/resource/providers/prefetch-handler.ts b/src/addon/mod/resource/providers/prefetch-handler.ts index bd439d42d..7c3e7be65 100644 --- a/src/addon/mod/resource/providers/prefetch-handler.ts +++ b/src/addon/mod/resource/providers/prefetch-handler.ts @@ -51,11 +51,18 @@ export class AddonModResourcePrefetchHandler extends CoreCourseResourcePrefetchH * @return {string} Status to display. */ determineStatus(module: any, status: string, canCheck: boolean): string { - if (status == CoreConstants.DOWNLOADED && module && module.contents) { - // If the first file is an external file, always display the module as outdated. - const mainFile = module.contents[0]; - if (mainFile && mainFile.isexternalfile) { - return CoreConstants.OUTDATED; + if (status == CoreConstants.DOWNLOADED && module) { + // If the main file is an external file, always display the module as outdated. + if (module.contentsinfo) { + if (module.contentsinfo.repositorytype) { + // It's an external file. + return CoreConstants.OUTDATED; + } + } else if (module.contents) { + const mainFile = module.contents[0]; + if (mainFile && mainFile.isexternalfile) { + return CoreConstants.OUTDATED; + } } } diff --git a/src/providers/utils/mimetype.ts b/src/providers/utils/mimetype.ts index 7ec3c895f..cac90bcb0 100644 --- a/src/providers/utils/mimetype.ts +++ b/src/providers/utils/mimetype.ts @@ -138,6 +138,37 @@ export class CoreMimetypeUtilsProvider { } } + /** + * Get the URL of the icon of an extension. + * + * @param {string} extension Extension. + * @return {string} Icon URL. + */ + getExtensionIcon(extension: string): string { + const icon = this.getExtensionIconName(extension) || 'unknown'; + + return this.getFileIconForType(icon); + } + + /** + * Get the name of the icon of an extension. + * + * @param {string} extension Extension. + * @return {string} Icon. Undefined if not found. + */ + getExtensionIconName(extension: string): string { + if (this.extToMime[extension]) { + if (this.extToMime[extension].icon) { + return this.extToMime[extension].icon; + } else { + const type = this.extToMime[extension].type.split('/')[0]; + if (type == 'video' || type == 'text' || type == 'image' || type == 'document' || type == 'audio') { + return type; + } + } + } + } + /** * Get the "type" (string) of an extension, something like "image", "video" or "audio". * @@ -172,19 +203,8 @@ export class CoreMimetypeUtilsProvider { * @return {string} The path to a file icon. */ getFileIcon(filename: string): string { - const ext = this.getFileExtension(filename); - let icon = 'unknown'; - - if (ext && this.extToMime[ext]) { - if (this.extToMime[ext].icon) { - icon = this.extToMime[ext].icon; - } else { - const type = this.extToMime[ext].type.split('/')[0]; - if (type == 'video' || type == 'text' || type == 'image' || type == 'document' || type == 'audio') { - icon = type; - } - } - } + const ext = this.getFileExtension(filename), + icon = this.getExtensionIconName(ext) || 'unknown'; return this.getFileIconForType(icon); } @@ -407,6 +427,30 @@ export class CoreMimetypeUtilsProvider { } } + /** + * Get the icon of a mimetype. + * + * @param {string} mimetype Mimetype. + * @return {string} Type of the mimetype. + */ + getMimetypeIcon(mimetype: string): string { + mimetype = mimetype.split(';')[0]; // Remove codecs from the mimetype if any. + + const extensions = this.mimeToExt[mimetype] || []; + let icon = 'unknown'; + + for (let i = 0; i < extensions.length; i++) { + const iconName = this.getExtensionIconName(extensions[i]); + + if (iconName) { + icon = iconName; + break; + } + } + + return this.getFileIconForType(icon); + } + /** * Given a group name, return the translated name. *