commit
e8a85c8f3f
|
@ -14,6 +14,7 @@
|
||||||
|
|
||||||
import { Component, Injector } from '@angular/core';
|
import { Component, Injector } from '@angular/core';
|
||||||
import { CoreAppProvider } from '@providers/app';
|
import { CoreAppProvider } from '@providers/app';
|
||||||
|
import { CoreSitesProvider } from '@providers/sites';
|
||||||
import { CoreCourseProvider } from '@core/course/providers/course';
|
import { CoreCourseProvider } from '@core/course/providers/course';
|
||||||
import { CoreCourseModuleMainResourceComponent } from '@core/course/classes/main-resource-component';
|
import { CoreCourseModuleMainResourceComponent } from '@core/course/classes/main-resource-component';
|
||||||
import { AddonModResourceProvider } from '../../providers/resource';
|
import { AddonModResourceProvider } from '../../providers/resource';
|
||||||
|
@ -37,7 +38,7 @@ export class AddonModResourceIndexComponent extends CoreCourseModuleMainResource
|
||||||
|
|
||||||
constructor(injector: Injector, private resourceProvider: AddonModResourceProvider, private courseProvider: CoreCourseProvider,
|
constructor(injector: Injector, private resourceProvider: AddonModResourceProvider, private courseProvider: CoreCourseProvider,
|
||||||
private appProvider: CoreAppProvider, private prefetchHandler: AddonModResourcePrefetchHandler,
|
private appProvider: CoreAppProvider, private prefetchHandler: AddonModResourcePrefetchHandler,
|
||||||
private resourceHelper: AddonModResourceHelperProvider) {
|
private resourceHelper: AddonModResourceHelperProvider, private sitesProvider: CoreSitesProvider) {
|
||||||
super(injector);
|
super(injector);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,6 +143,13 @@ export class AddonModResourceIndexComponent extends CoreCourseModuleMainResource
|
||||||
* Opens a file.
|
* Opens a file.
|
||||||
*/
|
*/
|
||||||
open(): void {
|
open(): void {
|
||||||
|
this.prefetchHandler.isDownloadable(this.module, this.courseId).then((downloadable) => {
|
||||||
|
if (downloadable) {
|
||||||
this.resourceHelper.openModuleFile(this.module, this.courseId);
|
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);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -113,7 +113,7 @@ export class AddonModResourceHelperProvider {
|
||||||
* @return {boolean} Whether the resource should be displayed embeded.
|
* @return {boolean} Whether the resource should be displayed embeded.
|
||||||
*/
|
*/
|
||||||
isDisplayedEmbedded(module: any, display: number): boolean {
|
isDisplayedEmbedded(module: any, display: number): boolean {
|
||||||
if (!module.contents.length || !this.fileProvider.isAvailable()) {
|
if (!module.contents.length || !this.fileProvider.isAvailable() || this.isNextcloudFile(module)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,6 +139,16 @@ export class AddonModResourceHelperProvider {
|
||||||
return mimetype == 'text/html';
|
return mimetype == 'text/html';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the resource is a Nextcloud file.
|
||||||
|
*
|
||||||
|
* @param {any} module Module to check.
|
||||||
|
* @return {boolean} Whether it's a Nextcloud file.
|
||||||
|
*/
|
||||||
|
isNextcloudFile(module: any): boolean {
|
||||||
|
return module.contents && module.contents[0] && module.contents[0].repositorytype == 'nextcloud';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens a file of the resource activity.
|
* Opens a file of the resource activity.
|
||||||
*
|
*
|
||||||
|
|
|
@ -23,6 +23,7 @@ import { CoreCourseProvider } from '@core/course/providers/course';
|
||||||
import { CoreCourseResourcePrefetchHandlerBase } from '@core/course/classes/resource-prefetch-handler';
|
import { CoreCourseResourcePrefetchHandlerBase } from '@core/course/classes/resource-prefetch-handler';
|
||||||
import { AddonModResourceProvider } from './resource';
|
import { AddonModResourceProvider } from './resource';
|
||||||
import { AddonModResourceHelperProvider } from './helper';
|
import { AddonModResourceHelperProvider } from './helper';
|
||||||
|
import { CoreConstants } from '@core/constants';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handler to prefetch resources.
|
* Handler to prefetch resources.
|
||||||
|
@ -41,6 +42,26 @@ export class AddonModResourcePrefetchHandler extends CoreCourseResourcePrefetchH
|
||||||
super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils);
|
super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the status to show based on current status.
|
||||||
|
*
|
||||||
|
* @param {any} module Module.
|
||||||
|
* @param {string} status The current status.
|
||||||
|
* @param {boolean} canCheck Whether the site allows checking for updates.
|
||||||
|
* @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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Download or prefetch the content.
|
* Download or prefetch the content.
|
||||||
*
|
*
|
||||||
|
@ -101,6 +122,20 @@ export class AddonModResourcePrefetchHandler extends CoreCourseResourcePrefetchH
|
||||||
return Promise.all(promises);
|
return Promise.all(promises);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a resource is downloadable.
|
||||||
|
*
|
||||||
|
* @param {any} module Module to check.
|
||||||
|
* @param {number} courseId Course ID the module belongs to.
|
||||||
|
* @return {Promise<boolean>} Promise resolved with true if downloadable, resolved with false otherwise.
|
||||||
|
*/
|
||||||
|
isDownloadable(module: any, courseId: number): Promise<boolean> {
|
||||||
|
// Don't allow downloading Nextcloud files for now.
|
||||||
|
return this.loadContents(module, courseId, false).then(() => {
|
||||||
|
return !this.resourceHelper.isNextcloudFile(module);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether or not the handler is enabled on a site level.
|
* Whether or not the handler is enabled on a site level.
|
||||||
*
|
*
|
||||||
|
|
|
@ -130,7 +130,18 @@ export class FileTransferObjectMock extends FileTransferObject {
|
||||||
|
|
||||||
xhr.onload = (): void => {
|
xhr.onload = (): void => {
|
||||||
// Finished dowloading the file.
|
// Finished dowloading the file.
|
||||||
let response = xhr.response;
|
let response = xhr.response || xhr.responseText;
|
||||||
|
|
||||||
|
const status = Math.max(xhr.status === 1223 ? 204 : xhr.status, 0);
|
||||||
|
if (status < 200 || status >= 300) {
|
||||||
|
// Request failed. Try to get the error message.
|
||||||
|
this.parseResponse(response).then((response) => {
|
||||||
|
reject(new FileTransferErrorMock(-1, source, target, xhr.status, response || xhr.statusText, null));
|
||||||
|
});
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!response) {
|
if (!response) {
|
||||||
reject();
|
reject();
|
||||||
} else {
|
} else {
|
||||||
|
@ -224,6 +235,51 @@ export class FileTransferObjectMock extends FileTransferObject {
|
||||||
this.progressListener = listener;
|
this.progressListener = listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Same as Javascript's JSON.parse, but it will handle errors.
|
||||||
|
*
|
||||||
|
* @param {string} json JSON text.
|
||||||
|
* @return {any} JSON parsed as object or what it gets.
|
||||||
|
*/
|
||||||
|
protected parseJSON(json: string): any {
|
||||||
|
try {
|
||||||
|
return JSON.parse(json);
|
||||||
|
} catch (ex) {
|
||||||
|
// Error.
|
||||||
|
}
|
||||||
|
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse a response, converting it into text and the into an object if needed.
|
||||||
|
*
|
||||||
|
* @param {any} response The response to parse.
|
||||||
|
* @return {Promise<any>} Promise resolved with the parsed response.
|
||||||
|
*/
|
||||||
|
protected parseResponse(response: any): Promise<any> {
|
||||||
|
return new Promise((resolve, reject): void => {
|
||||||
|
if (!response) {
|
||||||
|
resolve('');
|
||||||
|
} else if (response.toString && response.toString() == '[object Blob]') {
|
||||||
|
// Convert the Blob into text.
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.onloadend = (): void => {
|
||||||
|
resolve(reader.result);
|
||||||
|
};
|
||||||
|
reader.readAsText(response);
|
||||||
|
|
||||||
|
} else if (response.toString && response.toString() == '[object ArrayBuffer]') {
|
||||||
|
// Convert the ArrayBuffer into text.
|
||||||
|
resolve(String.fromCharCode.apply(null, new Uint8Array(response)));
|
||||||
|
} else {
|
||||||
|
resolve(response);
|
||||||
|
}
|
||||||
|
}).then((response: any) => {
|
||||||
|
return this.parseJSON(response);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends a file to a server.
|
* Sends a file to a server.
|
||||||
*
|
*
|
||||||
|
|
|
@ -2501,7 +2501,7 @@ export class CoreFilepoolProvider {
|
||||||
// File not in pool.
|
// File not in pool.
|
||||||
}).then((entry: CoreFilepoolFileEntry) => {
|
}).then((entry: CoreFilepoolFileEntry) => {
|
||||||
|
|
||||||
if (entry && !this.isFileOutdated(entry, options.revision, options.timemodified)) {
|
if (entry && !options.isexternalfile && !this.isFileOutdated(entry, options.revision, options.timemodified)) {
|
||||||
// We have the file, it is not stale, we can update links and remove from queue.
|
// We have the file, it is not stale, we can update links and remove from queue.
|
||||||
this.logger.debug('Queued file already in store, ignoring...');
|
this.logger.debug('Queued file already in store, ignoring...');
|
||||||
this.addFileLinks(siteId, fileId, links).catch(() => {
|
this.addFileLinks(siteId, fileId, links).catch(() => {
|
||||||
|
|
Loading…
Reference in New Issue