// (C) Copyright 2015 Moodle Pty Ltd. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. import { CoreConstants } from '@/core/constants'; import { Component, OnInit, Optional } from '@angular/core'; import { CoreError } from '@classes/errors/error'; 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 { CoreSites } from '@services/sites'; import { CoreMimetypeUtils } from '@services/utils/mimetype'; import { CoreTextUtils } from '@services/utils/text'; import { AddonModUrl, AddonModUrlDisplayOptions, AddonModUrlProvider, AddonModUrlUrl } from '../../services/url'; import { AddonModUrlHelper } from '../../services/url-helper'; /** * Component that displays a url. */ @Component({ selector: 'addon-mod-url-index', templateUrl: 'addon-mod-url-index.html', styleUrls: ['index.scss'], }) export class AddonModUrlIndexComponent extends CoreCourseModuleMainResourceComponent implements OnInit { component = AddonModUrlProvider.COMPONENT; url?: string; name?: string; shouldEmbed = false; shouldIframe = false; isImage = false; isAudio = false; isVideo = false; isOther = false; mimetype?: string; displayDescription = true; constructor(@Optional() courseContentsPage?: CoreCourseContentsPage) { super('AddonModUrlIndexComponent', courseContentsPage); } /** * Component being initialized. */ async ngOnInit(): Promise { super.ngOnInit(); await this.loadContent(); if ((this.shouldIframe || (this.shouldEmbed && this.isOther)) || (!this.shouldIframe && (!this.shouldEmbed || !this.isOther))) { this.logView(); } } /** * Perform the invalidate content function. * * @return Resolved when done. */ protected async invalidateContent(): Promise { await AddonModUrl.invalidateContent(this.module.id, this.courseId); } /** * Download url contents. * * @param refresh Whether we're refreshing data. * @return Promise resolved when done. */ protected async fetchContent(refresh = false): Promise { try { // Fetch the module data. const url = await AddonModUrl.getUrl(this.courseId, this.module.id); this.name = url.name; this.description = url.intro; this.dataRetrieved.emit(url); if (url.displayoptions) { const unserialized = CoreTextUtils.unserialize(url.displayoptions); this.displayDescription = typeof unserialized.printintro == 'undefined' || !!unserialized.printintro; } // Try to load module contents, it's needed to get the URL with parameters. await CoreCourse.loadModuleContents(this.module, this.courseId, undefined, false, refresh, undefined, 'url'); // 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; await this.calculateDisplayOptions(url); } catch { // Fallback in case is not prefetched. const mod = await CoreCourse.getModule(this.module.id, this.courseId, undefined, false, false, undefined, 'url'); this.name = mod.name; this.description = mod.description; this.dataRetrieved.emit(mod); if (!mod.contents.length) { // If the data was cached maybe we don't have contents. Reject. throw new CoreError('No contents found in module.'); } this.url = mod.contents && mod.contents[0] && mod.contents[0].fileurl ? mod.contents[0].fileurl : undefined; } } /** * Calculate the display options to determine how the URL should be rendered. * * @param url Object with the URL data. * @return Promise resolved when done. */ protected async calculateDisplayOptions(url: AddonModUrlUrl): Promise { const displayType = AddonModUrl.getFinalDisplayType(url); this.shouldEmbed = displayType == CoreConstants.RESOURCELIB_DISPLAY_EMBED; this.shouldIframe = displayType == CoreConstants.RESOURCELIB_DISPLAY_FRAME; if (this.shouldEmbed) { const extension = CoreMimetypeUtils.guessExtensionFromUrl(url.externalurl); this.mimetype = CoreMimetypeUtils.getMimeType(extension); this.isImage = CoreMimetypeUtils.isExtensionInGroup(extension, ['web_image']); this.isAudio = CoreMimetypeUtils.isExtensionInGroup(extension, ['web_audio']); this.isVideo = CoreMimetypeUtils.isExtensionInGroup(extension, ['web_video']); this.isOther = !this.isImage && !this.isAudio && !this.isVideo; } if (this.shouldIframe || (this.shouldEmbed && !this.isImage && !this.isAudio && !this.isVideo)) { // Will be displayed in an iframe. Check if we need to auto-login. const currentSite = CoreSites.getCurrentSite(); if (currentSite?.containsUrl(this.url)) { // Format the URL to add auto-login. this.url = await currentSite.getAutoLoginUrl(this.url!, false); } } } /** * Log view into the site and checks module completion. * * @return Promise resolved when done. */ protected async logView(): Promise { try { await AddonModUrl.logView(this.module.instance!, this.module.name); CoreCourse.checkModuleCompletion(this.courseId, this.module.completiondata); } catch { // Ignore errors. } } /** * Opens a file. */ go(): void { this.logView(); AddonModUrlHelper.open(this.url!); } }