Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions scripts/langindex.json
Original file line number Diff line number Diff line change
Expand Up @@ -1619,6 +1619,7 @@
"core.h5p.offlineDialogRetryButtonLabel": "h5p",
"core.h5p.offlineDialogRetryMessage": "h5p",
"core.h5p.offlineSuccessfulSubmit": "h5p",
"core.h5p.offlinedisabled": "local_moodlemobileapp",
"core.h5p.originator": "h5p",
"core.h5p.pd": "h5p",
"core.h5p.pddl": "h5p",
Expand Down
6 changes: 4 additions & 2 deletions src/addon/mod/book/components/index/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ export class AddonModBookIndexComponent extends CoreCourseModuleMainResourceComp
protected fetchContent(refresh?: boolean): Promise<any> {
const promises = [];
let downloadFailed = false;
let downloadFailError;

// Try to get the book data.
promises.push(this.bookProvider.getBook(this.courseId, this.module.id).then((book) => {
Expand All @@ -129,9 +130,10 @@ export class AddonModBookIndexComponent extends CoreCourseModuleMainResourceComp
}));

// Download content. This function also loads module contents if needed.
promises.push(this.prefetchDelegate.download(this.module, this.courseId).catch(() => {
promises.push(this.prefetchDelegate.download(this.module, this.courseId).catch((error) => {
// Mark download as failed but go on since the main files could have been downloaded.
downloadFailed = true;
downloadFailError = error;

if (!this.module.contents.length) {
// Try to load module contents for offline usage.
Expand Down Expand Up @@ -163,7 +165,7 @@ export class AddonModBookIndexComponent extends CoreCourseModuleMainResourceComp
return this.loadChapter(this.currentChapter).then(() => {
if (downloadFailed && this.appProvider.isOnline()) {
// We could load the main file but the download failed. Show error message.
this.domUtils.showErrorModal('core.errordownloadingsomefiles', true);
this.showErrorDownloadingSomeFiles(downloadFailError);
}
}).catch(() => {
// Ignore errors, they're handled inside the loadChapter function.
Expand Down
6 changes: 4 additions & 2 deletions src/addon/mod/imscp/components/index/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,16 +76,18 @@ export class AddonModImscpIndexComponent extends CoreCourseModuleMainResourceCom
*/
protected fetchContent(refresh?: boolean): Promise<any> {
let downloadFailed = false;
let downloadFailError;
const promises = [];

promises.push(this.imscpProvider.getImscp(this.courseId, this.module.id).then((imscp) => {
this.description = imscp.intro;
this.dataRetrieved.emit(imscp);
}));

promises.push(this.imscpPrefetch.download(this.module, this.courseId).catch(() => {
promises.push(this.imscpPrefetch.download(this.module, this.courseId).catch((error) => {
// Mark download as failed but go on since the main files could have been downloaded.
downloadFailed = true;
downloadFailError = error;

return this.courseProvider.loadModuleContents(this.module, this.courseId).catch((error) => {
// Error getting module contents, fail.
Expand All @@ -109,7 +111,7 @@ export class AddonModImscpIndexComponent extends CoreCourseModuleMainResourceCom
}).then(() => {
if (downloadFailed && this.appProvider.isOnline()) {
// We could load the main file but the download failed. Show error message.
this.domUtils.showErrorModal('core.errordownloadingsomefiles', true);
this.showErrorDownloadingSomeFiles(downloadFailError);
}

}).finally(() => {
Expand Down
6 changes: 4 additions & 2 deletions src/addon/mod/page/components/index/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,13 @@ export class AddonModPageIndexComponent extends CoreCourseModuleMainResourceComp
*/
protected fetchContent(refresh?: boolean): Promise<any> {
let downloadFailed = false;
let downloadFailError;

// Download content. This function also loads module contents if needed.
return this.pagePrefetch.download(this.module, this.courseId).catch(() => {
return this.pagePrefetch.download(this.module, this.courseId).catch((error) => {
// Mark download as failed but go on since the main files could have been downloaded.
downloadFailed = true;
downloadFailError = error;
}).then(() => {
if (!this.module.contents.length) {
// Try to load module contents for offline usage.
Expand Down Expand Up @@ -132,7 +134,7 @@ export class AddonModPageIndexComponent extends CoreCourseModuleMainResourceComp

if (downloadFailed && this.appProvider.isOnline()) {
// We could load the main file but the download failed. Show error message.
this.domUtils.showErrorModal('core.errordownloadingsomefiles', true);
this.showErrorDownloadingSomeFiles(downloadFailError);
}
}));

Expand Down
42 changes: 29 additions & 13 deletions src/addon/mod/resource/components/index/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

import { Component, Injector } from '@angular/core';
import { CoreAppProvider } from '@providers/app';
import { CoreFilepoolProvider } from '@providers/filepool';
import { CoreSitesProvider } from '@providers/sites';
import { CoreUtilsProvider } from '@providers/utils/utils';
import { CoreCourseProvider } from '@core/course/providers/course';
Expand All @@ -38,10 +39,15 @@ export class AddonModResourceIndexComponent extends CoreCourseModuleMainResource
contentText: string;
displayDescription = true;

constructor(injector: Injector, private resourceProvider: AddonModResourceProvider, private courseProvider: CoreCourseProvider,
private appProvider: CoreAppProvider, private prefetchHandler: AddonModResourcePrefetchHandler,
private resourceHelper: AddonModResourceHelperProvider, private sitesProvider: CoreSitesProvider,
private utils: CoreUtilsProvider) {
constructor(injector: Injector,
protected resourceProvider: AddonModResourceProvider,
protected courseProvider: CoreCourseProvider,
protected appProvider: CoreAppProvider,
protected prefetchHandler: AddonModResourcePrefetchHandler,
protected resourceHelper: AddonModResourceHelperProvider,
protected sitesProvider: CoreSitesProvider,
protected utils: CoreUtilsProvider,
protected filepoolProvider: CoreFilepoolProvider) {
super(injector);
}

Expand Down Expand Up @@ -104,10 +110,12 @@ export class AddonModResourceIndexComponent extends CoreCourseModuleMainResource

if (this.resourceHelper.isDisplayedInIframe(this.module)) {
let downloadFailed = false;
let downloadFailError;

return this.prefetchHandler.download(this.module, this.courseId).catch(() => {
return this.prefetchHandler.download(this.module, this.courseId).catch((error) => {
// Mark download as failed but go on since the main files could have been downloaded.
downloadFailed = true;
downloadFailError = error;
}).then(() => {
return this.resourceHelper.getIframeSrc(this.module).then((src) => {
this.mode = 'iframe';
Expand All @@ -125,7 +133,7 @@ export class AddonModResourceIndexComponent extends CoreCourseModuleMainResource

if (downloadFailed && this.appProvider.isOnline()) {
// We could load the main file but the download failed. Show error message.
this.domUtils.showErrorModal('core.errordownloadingsomefiles', true);
this.showErrorDownloadingSomeFiles(downloadFailError);
}
});
});
Expand All @@ -147,15 +155,23 @@ export class AddonModResourceIndexComponent extends CoreCourseModuleMainResource

/**
* Opens a file.
*
* @return Promise resolved when done.
*/
open(): void {
this.prefetchHandler.isDownloadable(this.module, this.courseId).then((downloadable) => {
async open(): Promise<void> {
let downloadable = await this.prefetchHandler.isDownloadable(this.module, this.courseId);

if (downloadable) {
// Check if the main file is downloadle.
// This isn't done in "isDownloadable" to prevent extra WS calls in the course page.
downloadable = await this.resourceHelper.isMainFileDownloadable(this.module);

if (downloadable) {
this.resourceHelper.openModuleFile(this.module, this.courseId);
} else {
// The resource cannot be downloaded, open the activity in browser.
return this.sitesProvider.getCurrentSite().openInBrowserWithAutoLoginIfSameSite(this.module.url);
return this.resourceHelper.openModuleFile(this.module, this.courseId);
}
});
}

// The resource cannot be downloaded, open the activity in browser.
return this.sitesProvider.getCurrentSite().openInBrowserWithAutoLoginIfSameSite(this.module.url);
}
}
34 changes: 29 additions & 5 deletions src/addon/mod/resource/providers/helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { AddonModResourceProvider } from './resource';
import { CoreSitesProvider } from '@providers/sites';
import { CoreFilepoolProvider } from '@providers/filepool';
import { CoreFileProvider } from '@providers/file';
import { CoreFileHelperProvider } from '@providers/file-helper';
import { CoreAppProvider } from '@providers/app';
import { CoreMimetypeUtilsProvider } from '@providers/utils/mimetype';
import { CoreTextUtilsProvider } from '@providers/utils/text';
Expand All @@ -36,11 +37,17 @@ export class AddonModResourceHelperProvider {
// Display using object tag.
protected DISPLAY_EMBED = 1;

constructor(private courseProvider: CoreCourseProvider, private domUtils: CoreDomUtilsProvider,
private resourceProvider: AddonModResourceProvider, private courseHelper: CoreCourseHelperProvider,
private textUtils: CoreTextUtilsProvider, private mimetypeUtils: CoreMimetypeUtilsProvider,
private fileProvider: CoreFileProvider, private appProvider: CoreAppProvider,
private filepoolProvider: CoreFilepoolProvider, private sitesProvider: CoreSitesProvider) {
constructor(protected courseProvider: CoreCourseProvider,
protected domUtils: CoreDomUtilsProvider,
protected resourceProvider: AddonModResourceProvider,
protected courseHelper: CoreCourseHelperProvider,
protected textUtils: CoreTextUtilsProvider,
protected mimetypeUtils: CoreMimetypeUtilsProvider,
protected fileProvider: CoreFileProvider,
protected appProvider: CoreAppProvider,
protected filepoolProvider: CoreFilepoolProvider,
protected sitesProvider: CoreSitesProvider,
protected fileHelper: CoreFileHelperProvider) {
}

/**
Expand Down Expand Up @@ -136,6 +143,23 @@ export class AddonModResourceHelperProvider {
return mimetype == 'text/html';
}

/**
* Check if main file of resource is downloadable.
*
* @param module Module instance.
* @param siteId Site ID. If not defined, current site.
* @return Promise resolved with boolean: whether main file is downloadable.
*/
isMainFileDownloadable(module: any, siteId?: string): Promise<boolean> {
siteId = siteId || this.sitesProvider.getCurrentSiteId();

const mainFile = module.contents[0];
const fileUrl = this.fileHelper.getFileUrl(mainFile);
const timemodified = this.fileHelper.getFileTimemodified(mainFile);

return this.filepoolProvider.isFileDownloadable(siteId, fileUrl, timemodified);
}

/**
* Check if the resource is a Nextcloud file.
*
Expand Down
1 change: 1 addition & 0 deletions src/assets/lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1619,6 +1619,7 @@
"core.h5p.offlineDialogRetryButtonLabel": "Retry now",
"core.h5p.offlineDialogRetryMessage": "Retrying in :num....",
"core.h5p.offlineSuccessfulSubmit": "Successfully submitted results.",
"core.h5p.offlinedisabled": "The site doesn't allow downloading H5P packages.",
"core.h5p.originator": "Originator",
"core.h5p.pd": "Public Domain",
"core.h5p.pddl": "Public Domain Dedication and Licence",
Expand Down
28 changes: 16 additions & 12 deletions src/components/file/file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { CoreFileHelperProvider } from '@providers/file-helper';
import { CoreSitesProvider } from '@providers/sites';
import { CoreDomUtilsProvider } from '@providers/utils/dom';
import { CoreMimetypeUtilsProvider } from '@providers/utils/mimetype';
import { CoreUrlUtilsProvider } from '@providers/utils/url';
import { CoreUtilsProvider } from '@providers/utils/utils';
import { CoreTextUtilsProvider } from '@providers/utils/text';
import { CoreConstants } from '@core/constants';
Expand Down Expand Up @@ -57,16 +58,17 @@ export class CoreFileComponent implements OnInit, OnDestroy {
protected timemodified: number;
protected observer;

constructor(private sitesProvider: CoreSitesProvider,
private utils: CoreUtilsProvider,
private domUtils: CoreDomUtilsProvider,
private filepoolProvider: CoreFilepoolProvider,
private appProvider: CoreAppProvider,
private fileHelper: CoreFileHelperProvider,
private mimeUtils: CoreMimetypeUtilsProvider,
private eventsProvider: CoreEventsProvider,
private textUtils: CoreTextUtilsProvider,
private pluginFileDelegate: CorePluginFileDelegate) {
constructor(protected sitesProvider: CoreSitesProvider,
protected utils: CoreUtilsProvider,
protected domUtils: CoreDomUtilsProvider,
protected filepoolProvider: CoreFilepoolProvider,
protected appProvider: CoreAppProvider,
protected fileHelper: CoreFileHelperProvider,
protected mimeUtils: CoreMimetypeUtilsProvider,
protected eventsProvider: CoreEventsProvider,
protected textUtils: CoreTextUtilsProvider,
protected pluginFileDelegate: CorePluginFileDelegate,
protected urlUtils: CoreUrlUtilsProvider) {
this.onDelete = new EventEmitter();
}

Expand Down Expand Up @@ -104,6 +106,8 @@ export class CoreFileComponent implements OnInit, OnDestroy {
this.observer = this.eventsProvider.on(eventName, () => {
this.calculateState();
});
}).catch(() => {
// File not downloadable.
});
}
}
Expand Down Expand Up @@ -152,14 +156,14 @@ export class CoreFileComponent implements OnInit, OnDestroy {
return;
}

if (!this.canDownload) {
if (!this.canDownload || !this.state || this.state == CoreConstants.NOT_DOWNLOADABLE) {
// File cannot be downloaded, just open it.
if (this.file.toURL) {
// Local file.
this.utils.openFile(this.file.toURL());
} else if (this.fileUrl) {
if (this.fileUrl.indexOf('http') === 0) {
this.utils.openOnlineFile(this.fileUrl);
this.utils.openOnlineFile(this.urlUtils.unfixPluginfileURL(this.fileUrl));
} else {
this.utils.openFile(this.fileUrl);
}
Expand Down
16 changes: 15 additions & 1 deletion src/core/course/classes/main-resource-component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { NavController } from 'ionic-angular';
import { TranslateService } from '@ngx-translate/core';
import { CoreLoggerProvider } from '@providers/logger';
import { CoreDomUtilsProvider } from '@providers/utils/dom';
import { CoreTextUtilsProvider } from '@providers/utils/text';
import { CoreTextUtilsProvider, CoreTextErrorObject } from '@providers/utils/text';
import { CoreCourseHelperProvider } from '@core/course/providers/helper';
import { CoreCourseModuleMainComponent, CoreCourseModuleDelegate } from '@core/course/providers/module-delegate';
import { CoreCourseSectionPage } from '@core/course/pages/section/section.ts';
Expand Down Expand Up @@ -265,6 +265,20 @@ export class CoreCourseModuleMainResourceComponent implements OnInit, OnDestroy,
this.courseHelper.confirmAndRemoveFiles(this.module, this.courseId);
}

/**
* Show an error occurred while downloading files.
*
* @param error The specific error.
*/
protected showErrorDownloadingSomeFiles(error: string | CoreTextErrorObject): void {
const errorMessage = this.textUtils.buildSeveralParagraphsMessage([
this.translate.instant('core.errordownloadingsomefiles'),
error,
]);

this.domUtils.showErrorModal(errorMessage);
}

/**
* Component being destroyed.
*/
Expand Down
5 changes: 3 additions & 2 deletions src/core/courses/providers/course-link-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,8 +178,9 @@ export class CoreCoursesCourseLinkHandler extends CoreContentLinksHandlerBase {
error = this.translate.instant('core.courses.notenroled');
}

const body = this.translate.instant('core.twoparagraphs',
{ p1: error, p2: this.translate.instant('core.confirmopeninbrowser') });
const body = this.textUtils.buildSeveralParagraphsMessage(
[error, this.translate.instant('core.confirmopeninbrowser')]);

this.domUtils.showConfirm(body).then(() => {
this.sitesProvider.getCurrentSite().openInBrowserWithAutoLogin(url);
}).catch(() => {
Expand Down
3 changes: 2 additions & 1 deletion src/core/h5p/components/h5p-player/h5p-player.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ export class CoreH5PPlayerComponent implements OnInit, OnChanges, OnDestroy {
this.logger = loggerProvider.getInstance('CoreH5PPlayerComponent');
this.site = sitesProvider.getCurrentSite();
this.siteId = this.site.getId();
this.siteCanDownload = this.sitesProvider.getCurrentSite().canDownloadFiles();
this.siteCanDownload = this.sitesProvider.getCurrentSite().canDownloadFiles() &&
!this.h5pProvider.isOfflineDisabledInSite();
}

/**
Expand Down
1 change: 1 addition & 0 deletions src/core/h5p/lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
"offlineDialogRetryButtonLabel": "Retry now",
"offlineDialogRetryMessage": "Retrying in :num....",
"offlineSuccessfulSubmit": "Successfully submitted results.",
"offlinedisabled": "The site doesn't allow downloading H5P packages.",
"originator": "Originator",
"pd": "Public Domain",
"pddl": "Public Domain Dedication and Licence",
Expand Down
24 changes: 24 additions & 0 deletions src/core/h5p/providers/h5p.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1876,6 +1876,30 @@ export class CoreH5PProvider {
});
}

/**
* Check whether H5P offline is disabled.
*
* @param siteId Site ID. If not defined, current site.
* @return Promise resolved with boolean: whether is disabled.
*/
async isOfflineDisabled(siteId?: string): Promise<boolean> {
const site = await this.sitesProvider.getSite(siteId);

return this.isOfflineDisabledInSite(site);
}

/**
* Check whether H5P offline is disabled.
*
* @param site Site instance. If not defined, current site.
* @return Whether is disabled.
*/
isOfflineDisabledInSite(site?: CoreSite): boolean {
site = site || this.sitesProvider.getCurrentSite();

return site.isFeatureDisabled('NoDelegate_H5POffline');
}

/**
* Performs actions required when a library has been installed.
*
Expand Down
Loading