Merge pull request #2352 from dpalou/MOBILE-3375
MOBILE-3375 course: Make download warnings less intrusivemain
commit
8497c7bac1
|
@ -18,6 +18,10 @@
|
||||||
|
|
||||||
<core-course-module-description [description]="description" [component]="component" [componentId]="componentId" contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"></core-course-module-description>
|
<core-course-module-description [description]="description" [component]="component" [componentId]="componentId" contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"></core-course-module-description>
|
||||||
|
|
||||||
|
<ion-card class="core-warning-card" icon-start *ngIf="warning">
|
||||||
|
<ion-icon name="warning"></ion-icon> <span [innerHTML]="warning"></span>
|
||||||
|
</ion-card>
|
||||||
|
|
||||||
<div padding class="safe-padding-horizontal">
|
<div padding class="safe-padding-horizontal">
|
||||||
<core-navigation-bar *ngIf="displayNavBar" [previous]="previousChapter && previousChapter.id" [previousTitle]="previousNavBarTitle" [next]="nextChapter && nextChapter.id" [nextTitle]="nextNavBarTitle" (action)="changeChapter($event)"></core-navigation-bar>
|
<core-navigation-bar *ngIf="displayNavBar" [previous]="previousChapter && previousChapter.id" [previousTitle]="previousNavBarTitle" [next]="nextChapter && nextChapter.id" [nextTitle]="nextNavBarTitle" (action)="changeChapter($event)"></core-navigation-bar>
|
||||||
<core-format-text [component]="component" [componentId]="componentId" [text]="chapterContent" contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"></core-format-text>
|
<core-format-text [component]="component" [componentId]="componentId" [text]="chapterContent" contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"></core-format-text>
|
||||||
|
|
|
@ -16,7 +16,9 @@ import { Component, Optional, Injector, Input } from '@angular/core';
|
||||||
import { Content, ModalController } from 'ionic-angular';
|
import { Content, ModalController } from 'ionic-angular';
|
||||||
import { CoreAppProvider } from '@providers/app';
|
import { CoreAppProvider } from '@providers/app';
|
||||||
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, CoreCourseResourceDownloadResult
|
||||||
|
} from '@core/course/classes/main-resource-component';
|
||||||
import {
|
import {
|
||||||
AddonModBookProvider, AddonModBookContentsMap, AddonModBookTocChapter, AddonModBookBook, AddonModBookNavStyle
|
AddonModBookProvider, AddonModBookContentsMap, AddonModBookTocChapter, AddonModBookBook, AddonModBookNavStyle
|
||||||
} from '../../providers/book';
|
} from '../../providers/book';
|
||||||
|
@ -41,6 +43,7 @@ export class AddonModBookIndexComponent extends CoreCourseModuleMainResourceComp
|
||||||
displayNavBar = true;
|
displayNavBar = true;
|
||||||
previousNavBarTitle: string;
|
previousNavBarTitle: string;
|
||||||
nextNavBarTitle: string;
|
nextNavBarTitle: string;
|
||||||
|
warning: string;
|
||||||
|
|
||||||
protected chapters: AddonModBookTocChapter[];
|
protected chapters: AddonModBookTocChapter[];
|
||||||
protected currentChapter: string;
|
protected currentChapter: string;
|
||||||
|
@ -48,9 +51,11 @@ export class AddonModBookIndexComponent extends CoreCourseModuleMainResourceComp
|
||||||
protected book: AddonModBookBook;
|
protected book: AddonModBookBook;
|
||||||
protected displayTitlesInNavBar = false;
|
protected displayTitlesInNavBar = false;
|
||||||
|
|
||||||
constructor(injector: Injector, private bookProvider: AddonModBookProvider, private courseProvider: CoreCourseProvider,
|
constructor(injector: Injector,
|
||||||
private appProvider: CoreAppProvider, private prefetchDelegate: AddonModBookPrefetchHandler,
|
protected bookProvider: AddonModBookProvider,
|
||||||
private modalCtrl: ModalController, private tagProvider: CoreTagProvider, @Optional() private content: Content) {
|
protected modalCtrl: ModalController,
|
||||||
|
protected tagProvider: CoreTagProvider,
|
||||||
|
@Optional() protected content: Content) {
|
||||||
super(injector);
|
super(injector);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,8 +131,7 @@ export class AddonModBookIndexComponent extends CoreCourseModuleMainResourceComp
|
||||||
*/
|
*/
|
||||||
protected fetchContent(refresh?: boolean): Promise<any> {
|
protected fetchContent(refresh?: boolean): Promise<any> {
|
||||||
const promises = [];
|
const promises = [];
|
||||||
let downloadFailed = false;
|
let downloadResult: CoreCourseResourceDownloadResult;
|
||||||
let downloadFailError;
|
|
||||||
|
|
||||||
// Try to get the book data.
|
// Try to get the book data.
|
||||||
promises.push(this.bookProvider.getBook(this.courseId, this.module.id).then((book) => {
|
promises.push(this.bookProvider.getBook(this.courseId, this.module.id).then((book) => {
|
||||||
|
@ -140,16 +144,9 @@ export class AddonModBookIndexComponent extends CoreCourseModuleMainResourceComp
|
||||||
// Ignore errors since this WS isn't available in some Moodle versions.
|
// Ignore errors since this WS isn't available in some Moodle versions.
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Download content. This function also loads module contents if needed.
|
// Get module status to determine if it needs to be downloaded.
|
||||||
promises.push(this.prefetchDelegate.download(this.module, this.courseId).catch((error) => {
|
promises.push(this.downloadResourceIfNeeded(refresh).then((result) => {
|
||||||
// Mark download as failed but go on since the main files could have been downloaded.
|
downloadResult = result;
|
||||||
downloadFailed = true;
|
|
||||||
downloadFailError = error;
|
|
||||||
|
|
||||||
if (!this.module.contents.length) {
|
|
||||||
// Try to load module contents for offline usage.
|
|
||||||
return this.courseProvider.loadModuleContents(this.module, this.courseId);
|
|
||||||
}
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
return Promise.all(promises).then(() => {
|
return Promise.all(promises).then(() => {
|
||||||
|
@ -174,10 +171,7 @@ export class AddonModBookIndexComponent extends CoreCourseModuleMainResourceComp
|
||||||
|
|
||||||
// Show chapter.
|
// Show chapter.
|
||||||
return this.loadChapter(this.currentChapter, refresh).then(() => {
|
return this.loadChapter(this.currentChapter, refresh).then(() => {
|
||||||
if (downloadFailed && this.appProvider.isOnline()) {
|
this.warning = downloadResult.failed ? this.getErrorDownloadingSomeFilesMessage(downloadResult.error) : '';
|
||||||
// We could load the main file but the download failed. Show error message.
|
|
||||||
this.showErrorDownloadingSomeFiles(downloadFailError);
|
|
||||||
}
|
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
// Ignore errors, they're handled inside the loadChapter function.
|
// Ignore errors, they're handled inside the loadChapter function.
|
||||||
});
|
});
|
||||||
|
|
|
@ -13,8 +13,6 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Component, Input, Injector } from '@angular/core';
|
import { Component, Input, Injector } from '@angular/core';
|
||||||
import { CoreAppProvider } from '@providers/app';
|
|
||||||
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 { AddonModFolderProvider } from '../../providers/folder';
|
import { AddonModFolderProvider } from '../../providers/folder';
|
||||||
import { AddonModFolderHelperProvider } from '../../providers/helper';
|
import { AddonModFolderHelperProvider } from '../../providers/helper';
|
||||||
|
@ -36,8 +34,9 @@ export class AddonModFolderIndexComponent extends CoreCourseModuleMainResourceCo
|
||||||
canGetFolder: boolean;
|
canGetFolder: boolean;
|
||||||
contents: any;
|
contents: any;
|
||||||
|
|
||||||
constructor(injector: Injector, private folderProvider: AddonModFolderProvider, private courseProvider: CoreCourseProvider,
|
constructor(injector: Injector,
|
||||||
private appProvider: CoreAppProvider, private folderHelper: AddonModFolderHelperProvider) {
|
protected folderProvider: AddonModFolderProvider,
|
||||||
|
protected folderHelper: AddonModFolderHelperProvider) {
|
||||||
super(injector);
|
super(injector);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,11 @@
|
||||||
|
|
||||||
<!-- Content. -->
|
<!-- Content. -->
|
||||||
<core-loading [hideUntil]="loaded" class="core-loading-center safe-area-page">
|
<core-loading [hideUntil]="loaded" class="core-loading-center safe-area-page">
|
||||||
|
|
||||||
|
<ion-card class="core-warning-card" icon-start *ngIf="warning">
|
||||||
|
<ion-icon name="warning"></ion-icon> <span [innerHTML]="warning"></span>
|
||||||
|
</ion-card>
|
||||||
|
|
||||||
<div class="addon-mod-imscp-container">
|
<div class="addon-mod-imscp-container">
|
||||||
<core-navigation-bar [previous]="previousItem" [next]="nextItem" (action)="loadItem($event)" [info]="description" [title]="'core.description' | translate" [component]="component" [componentId]="componentId" contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"></core-navigation-bar>
|
<core-navigation-bar [previous]="previousItem" [next]="nextItem" (action)="loadItem($event)" [info]="description" [title]="'core.description' | translate" [component]="component" [componentId]="componentId" contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"></core-navigation-bar>
|
||||||
<core-iframe [src]="src"></core-iframe>
|
<core-iframe [src]="src"></core-iframe>
|
||||||
|
|
|
@ -14,11 +14,10 @@
|
||||||
|
|
||||||
import { Component, Injector } from '@angular/core';
|
import { Component, Injector } from '@angular/core';
|
||||||
import { ModalController } from 'ionic-angular';
|
import { ModalController } from 'ionic-angular';
|
||||||
import { CoreAppProvider } from '@providers/app';
|
import {
|
||||||
import { CoreCourseProvider } from '@core/course/providers/course';
|
CoreCourseModuleMainResourceComponent, CoreCourseResourceDownloadResult
|
||||||
import { CoreCourseModuleMainResourceComponent } from '@core/course/classes/main-resource-component';
|
} from '@core/course/classes/main-resource-component';
|
||||||
import { AddonModImscpProvider } from '../../providers/imscp';
|
import { AddonModImscpProvider } from '../../providers/imscp';
|
||||||
import { AddonModImscpPrefetchHandler } from '../../providers/prefetch-handler';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component that displays a IMSCP.
|
* Component that displays a IMSCP.
|
||||||
|
@ -33,14 +32,15 @@ export class AddonModImscpIndexComponent extends CoreCourseModuleMainResourceCom
|
||||||
items = [];
|
items = [];
|
||||||
currentItem: string;
|
currentItem: string;
|
||||||
src = '';
|
src = '';
|
||||||
|
warning: string;
|
||||||
|
|
||||||
// Initialize empty previous/next to prevent showing arrows for an instant before they're hidden.
|
// Initialize empty previous/next to prevent showing arrows for an instant before they're hidden.
|
||||||
previousItem = '';
|
previousItem = '';
|
||||||
nextItem = '';
|
nextItem = '';
|
||||||
|
|
||||||
constructor(injector: Injector, private imscpProvider: AddonModImscpProvider, private courseProvider: CoreCourseProvider,
|
constructor(injector: Injector,
|
||||||
private appProvider: CoreAppProvider, private modalCtrl: ModalController,
|
protected imscpProvider: AddonModImscpProvider,
|
||||||
private imscpPrefetch: AddonModImscpPrefetchHandler) {
|
protected modalCtrl: ModalController) {
|
||||||
super(injector);
|
super(injector);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,8 +75,7 @@ export class AddonModImscpIndexComponent extends CoreCourseModuleMainResourceCom
|
||||||
* @return Promise resolved when done.
|
* @return Promise resolved when done.
|
||||||
*/
|
*/
|
||||||
protected fetchContent(refresh?: boolean): Promise<any> {
|
protected fetchContent(refresh?: boolean): Promise<any> {
|
||||||
let downloadFailed = false;
|
let downloadResult: CoreCourseResourceDownloadResult;
|
||||||
let downloadFailError;
|
|
||||||
const promises = [];
|
const promises = [];
|
||||||
|
|
||||||
promises.push(this.imscpProvider.getImscp(this.courseId, this.module.id).then((imscp) => {
|
promises.push(this.imscpProvider.getImscp(this.courseId, this.module.id).then((imscp) => {
|
||||||
|
@ -84,17 +83,8 @@ export class AddonModImscpIndexComponent extends CoreCourseModuleMainResourceCom
|
||||||
this.dataRetrieved.emit(imscp);
|
this.dataRetrieved.emit(imscp);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
promises.push(this.imscpPrefetch.download(this.module, this.courseId).catch((error) => {
|
promises.push(this.downloadResourceIfNeeded(refresh).then((result) => {
|
||||||
// Mark download as failed but go on since the main files could have been downloaded.
|
downloadResult = result;
|
||||||
downloadFailed = true;
|
|
||||||
downloadFailError = error;
|
|
||||||
|
|
||||||
return this.courseProvider.loadModuleContents(this.module, this.courseId).catch((error) => {
|
|
||||||
// Error getting module contents, fail.
|
|
||||||
this.domUtils.showErrorModalDefault(error, 'core.course.errorgetmodule', true);
|
|
||||||
|
|
||||||
return Promise.reject(null);
|
|
||||||
});
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
return Promise.all(promises).then(() => {
|
return Promise.all(promises).then(() => {
|
||||||
|
@ -109,10 +99,7 @@ export class AddonModImscpIndexComponent extends CoreCourseModuleMainResourceCom
|
||||||
return Promise.reject(null);
|
return Promise.reject(null);
|
||||||
});
|
});
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
if (downloadFailed && this.appProvider.isOnline()) {
|
this.warning = downloadResult.failed ? this.getErrorDownloadingSomeFilesMessage(downloadResult.error) : '';
|
||||||
// We could load the main file but the download failed. Show error message.
|
|
||||||
this.showErrorDownloadingSomeFiles(downloadFailError);
|
|
||||||
}
|
|
||||||
|
|
||||||
}).finally(() => {
|
}).finally(() => {
|
||||||
this.fillContextMenu(refresh);
|
this.fillContextMenu(refresh);
|
||||||
|
|
|
@ -15,6 +15,10 @@
|
||||||
|
|
||||||
<core-course-module-description *ngIf="displayDescription" [description]="description" [component]="component" [componentId]="componentId" contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"></core-course-module-description>
|
<core-course-module-description *ngIf="displayDescription" [description]="description" [component]="component" [componentId]="componentId" contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"></core-course-module-description>
|
||||||
|
|
||||||
|
<ion-card class="core-warning-card" icon-start *ngIf="warning">
|
||||||
|
<ion-icon name="warning"></ion-icon> <span [innerHTML]="warning"></span>
|
||||||
|
</ion-card>
|
||||||
|
|
||||||
<div padding>
|
<div padding>
|
||||||
<core-format-text [component]="component" [componentId]="componentId" [text]="contents" contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"></core-format-text>
|
<core-format-text [component]="component" [componentId]="componentId" [text]="contents" contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"></core-format-text>
|
||||||
<p padding-bottom class="addon-mod_page-timemodified" *ngIf="displayTimemodified && page && page.timemodified">
|
<p padding-bottom class="addon-mod_page-timemodified" *ngIf="displayTimemodified && page && page.timemodified">
|
||||||
|
|
|
@ -13,13 +13,12 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Component, Injector } from '@angular/core';
|
import { Component, Injector } from '@angular/core';
|
||||||
import { CoreAppProvider } from '@providers/app';
|
|
||||||
import { CoreUtilsProvider } from '@providers/utils/utils';
|
import { CoreUtilsProvider } from '@providers/utils/utils';
|
||||||
import { CoreCourseProvider } from '@core/course/providers/course';
|
import {
|
||||||
import { CoreCourseModuleMainResourceComponent } from '@core/course/classes/main-resource-component';
|
CoreCourseModuleMainResourceComponent, CoreCourseResourceDownloadResult
|
||||||
|
} from '@core/course/classes/main-resource-component';
|
||||||
import { AddonModPageProvider, AddonModPagePage } from '../../providers/page';
|
import { AddonModPageProvider, AddonModPagePage } from '../../providers/page';
|
||||||
import { AddonModPageHelperProvider } from '../../providers/helper';
|
import { AddonModPageHelperProvider } from '../../providers/helper';
|
||||||
import { AddonModPagePrefetchHandler } from '../../providers/prefetch-handler';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component that displays a page.
|
* Component that displays a page.
|
||||||
|
@ -35,12 +34,14 @@ export class AddonModPageIndexComponent extends CoreCourseModuleMainResourceComp
|
||||||
displayDescription = true;
|
displayDescription = true;
|
||||||
displayTimemodified = true;
|
displayTimemodified = true;
|
||||||
page: AddonModPagePage;
|
page: AddonModPagePage;
|
||||||
|
warning: string;
|
||||||
|
|
||||||
protected fetchContentDefaultError = 'addon.mod_page.errorwhileloadingthepage';
|
protected fetchContentDefaultError = 'addon.mod_page.errorwhileloadingthepage';
|
||||||
|
|
||||||
constructor(injector: Injector, private pageProvider: AddonModPageProvider, private courseProvider: CoreCourseProvider,
|
constructor(injector: Injector,
|
||||||
private appProvider: CoreAppProvider, private pageHelper: AddonModPageHelperProvider,
|
protected pageProvider: AddonModPageProvider,
|
||||||
private pagePrefetch: AddonModPagePrefetchHandler, private utils: CoreUtilsProvider) {
|
protected pageHelper: AddonModPageHelperProvider,
|
||||||
|
protected utils: CoreUtilsProvider) {
|
||||||
super(injector);
|
super(injector);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,19 +78,11 @@ export class AddonModPageIndexComponent extends CoreCourseModuleMainResourceComp
|
||||||
* @return Promise resolved when done.
|
* @return Promise resolved when done.
|
||||||
*/
|
*/
|
||||||
protected fetchContent(refresh?: boolean): Promise<any> {
|
protected fetchContent(refresh?: boolean): Promise<any> {
|
||||||
let downloadFailed = false;
|
let downloadResult: CoreCourseResourceDownloadResult;
|
||||||
let downloadFailError;
|
|
||||||
|
|
||||||
// Download content. This function also loads module contents if needed.
|
// Download the resource if it needs to be downloaded.
|
||||||
return this.pagePrefetch.download(this.module, this.courseId).catch((error) => {
|
return this.downloadResourceIfNeeded(refresh).then((result) => {
|
||||||
// Mark download as failed but go on since the main files could have been downloaded.
|
downloadResult = result;
|
||||||
downloadFailed = true;
|
|
||||||
downloadFailError = error;
|
|
||||||
}).then(() => {
|
|
||||||
if (!this.module.contents.length) {
|
|
||||||
// Try to load module contents for offline usage.
|
|
||||||
return this.courseProvider.loadModuleContents(this.module, this.courseId);
|
|
||||||
}
|
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
const promises = [];
|
const promises = [];
|
||||||
|
|
||||||
|
@ -131,11 +124,7 @@ export class AddonModPageIndexComponent extends CoreCourseModuleMainResourceComp
|
||||||
promises.push(this.pageHelper.getPageHtml(this.module.contents, this.module.id).then((content) => {
|
promises.push(this.pageHelper.getPageHtml(this.module.contents, this.module.id).then((content) => {
|
||||||
|
|
||||||
this.contents = content;
|
this.contents = content;
|
||||||
|
this.warning = downloadResult.failed ? this.getErrorDownloadingSomeFilesMessage(downloadResult.error) : '';
|
||||||
if (downloadFailed && this.appProvider.isOnline()) {
|
|
||||||
// We could load the main file but the download failed. Show error message.
|
|
||||||
this.showErrorDownloadingSomeFiles(downloadFailError);
|
|
||||||
}
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
return Promise.all(promises);
|
return Promise.all(promises);
|
||||||
|
|
|
@ -15,6 +15,10 @@
|
||||||
|
|
||||||
<core-course-module-description *ngIf="mode != 'iframe' && (mode != 'embedded' || displayDescription)" [description]="description" [component]="component" [componentId]="componentId" contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"></core-course-module-description>
|
<core-course-module-description *ngIf="mode != 'iframe' && (mode != 'embedded' || displayDescription)" [description]="description" [component]="component" [componentId]="componentId" contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"></core-course-module-description>
|
||||||
|
|
||||||
|
<ion-card class="core-warning-card" icon-start *ngIf="warning">
|
||||||
|
<ion-icon name="warning"></ion-icon> <span [innerHTML]="warning"></span>
|
||||||
|
</ion-card>
|
||||||
|
|
||||||
<ng-container *ngIf="mode == 'iframe'">
|
<ng-container *ngIf="mode == 'iframe'">
|
||||||
<core-iframe [src]="src"></core-iframe>
|
<core-iframe [src]="src"></core-iframe>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
|
@ -13,14 +13,12 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Component, Injector } from '@angular/core';
|
import { Component, Injector } from '@angular/core';
|
||||||
import { CoreAppProvider } from '@providers/app';
|
|
||||||
import { CoreFilepoolProvider } from '@providers/filepool';
|
import { CoreFilepoolProvider } from '@providers/filepool';
|
||||||
import { CoreSitesProvider } from '@providers/sites';
|
|
||||||
import { CoreUtilsProvider } from '@providers/utils/utils';
|
import { CoreUtilsProvider } from '@providers/utils/utils';
|
||||||
import { CoreCourseProvider } from '@core/course/providers/course';
|
import {
|
||||||
import { CoreCourseModuleMainResourceComponent } from '@core/course/classes/main-resource-component';
|
CoreCourseModuleMainResourceComponent, CoreCourseResourceDownloadResult
|
||||||
|
} from '@core/course/classes/main-resource-component';
|
||||||
import { AddonModResourceProvider } from '../../providers/resource';
|
import { AddonModResourceProvider } from '../../providers/resource';
|
||||||
import { AddonModResourcePrefetchHandler } from '../../providers/prefetch-handler';
|
|
||||||
import { AddonModResourceHelperProvider } from '../../providers/helper';
|
import { AddonModResourceHelperProvider } from '../../providers/helper';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -38,14 +36,11 @@ export class AddonModResourceIndexComponent extends CoreCourseModuleMainResource
|
||||||
src: string;
|
src: string;
|
||||||
contentText: string;
|
contentText: string;
|
||||||
displayDescription = true;
|
displayDescription = true;
|
||||||
|
warning: string;
|
||||||
|
|
||||||
constructor(injector: Injector,
|
constructor(injector: Injector,
|
||||||
protected resourceProvider: AddonModResourceProvider,
|
protected resourceProvider: AddonModResourceProvider,
|
||||||
protected courseProvider: CoreCourseProvider,
|
|
||||||
protected appProvider: CoreAppProvider,
|
|
||||||
protected prefetchHandler: AddonModResourcePrefetchHandler,
|
|
||||||
protected resourceHelper: AddonModResourceHelperProvider,
|
protected resourceHelper: AddonModResourceHelperProvider,
|
||||||
protected sitesProvider: CoreSitesProvider,
|
|
||||||
protected utils: CoreUtilsProvider,
|
protected utils: CoreUtilsProvider,
|
||||||
protected filepoolProvider: CoreFilepoolProvider) {
|
protected filepoolProvider: CoreFilepoolProvider) {
|
||||||
super(injector);
|
super(injector);
|
||||||
|
@ -109,13 +104,10 @@ export class AddonModResourceIndexComponent extends CoreCourseModuleMainResource
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.resourceHelper.isDisplayedInIframe(this.module)) {
|
if (this.resourceHelper.isDisplayedInIframe(this.module)) {
|
||||||
let downloadFailed = false;
|
let downloadResult: CoreCourseResourceDownloadResult;
|
||||||
let downloadFailError;
|
|
||||||
|
|
||||||
return this.prefetchHandler.download(this.module, this.courseId).catch((error) => {
|
return this.downloadResourceIfNeeded(refresh, true).then((result) => {
|
||||||
// Mark download as failed but go on since the main files could have been downloaded.
|
downloadResult = result;
|
||||||
downloadFailed = true;
|
|
||||||
downloadFailError = error;
|
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
return this.resourceHelper.getIframeSrc(this.module).then((src) => {
|
return this.resourceHelper.getIframeSrc(this.module).then((src) => {
|
||||||
this.mode = 'iframe';
|
this.mode = 'iframe';
|
||||||
|
@ -131,14 +123,12 @@ export class AddonModResourceIndexComponent extends CoreCourseModuleMainResource
|
||||||
this.src = src;
|
this.src = src;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (downloadFailed && this.appProvider.isOnline()) {
|
this.warning = downloadResult.failed ? this.getErrorDownloadingSomeFilesMessage(downloadResult.error) : '';
|
||||||
// We could load the main file but the download failed. Show error message.
|
|
||||||
this.showErrorDownloadingSomeFiles(downloadFailError);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
} else if (this.resourceHelper.isDisplayedEmbedded(this.module, resource && resource.display)) {
|
} else if (this.resourceHelper.isDisplayedEmbedded(this.module, resource && resource.display)) {
|
||||||
this.mode = 'embedded';
|
this.mode = 'embedded';
|
||||||
|
this.warning = '';
|
||||||
|
|
||||||
return this.resourceHelper.getEmbeddedHtml(this.module, this.courseId).then((html) => {
|
return this.resourceHelper.getEmbeddedHtml(this.module, this.courseId).then((html) => {
|
||||||
this.contentText = html;
|
this.contentText = html;
|
||||||
|
@ -147,6 +137,7 @@ export class AddonModResourceIndexComponent extends CoreCourseModuleMainResource
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.mode = 'external';
|
this.mode = 'external';
|
||||||
|
this.warning = '';
|
||||||
}
|
}
|
||||||
}).finally(() => {
|
}).finally(() => {
|
||||||
this.fillContextMenu(refresh);
|
this.fillContextMenu(refresh);
|
||||||
|
@ -159,7 +150,7 @@ export class AddonModResourceIndexComponent extends CoreCourseModuleMainResource
|
||||||
* @return Promise resolved when done.
|
* @return Promise resolved when done.
|
||||||
*/
|
*/
|
||||||
async open(): Promise<void> {
|
async open(): Promise<void> {
|
||||||
let downloadable = await this.prefetchHandler.isDownloadable(this.module, this.courseId);
|
let downloadable = await this.modulePrefetchDelegate.isModuleDownloadable(this.module, this.courseId);
|
||||||
|
|
||||||
if (downloadable) {
|
if (downloadable) {
|
||||||
// Check if the main file is downloadle.
|
// Check if the main file is downloadle.
|
||||||
|
|
|
@ -13,9 +13,7 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Component, Injector } from '@angular/core';
|
import { Component, Injector } from '@angular/core';
|
||||||
import { CoreSitesProvider } from '@providers/sites';
|
|
||||||
import { CoreMimetypeUtilsProvider } from '@providers/utils/mimetype';
|
import { CoreMimetypeUtilsProvider } from '@providers/utils/mimetype';
|
||||||
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 { AddonModUrlProvider } from '../../providers/url';
|
import { AddonModUrlProvider } from '../../providers/url';
|
||||||
import { AddonModUrlHelperProvider } from '../../providers/helper';
|
import { AddonModUrlHelperProvider } from '../../providers/helper';
|
||||||
|
@ -43,9 +41,10 @@ export class AddonModUrlIndexComponent extends CoreCourseModuleMainResourceCompo
|
||||||
mimetype: string;
|
mimetype: string;
|
||||||
displayDescription = true;
|
displayDescription = true;
|
||||||
|
|
||||||
constructor(injector: Injector, private urlProvider: AddonModUrlProvider, private courseProvider: CoreCourseProvider,
|
constructor(injector: Injector,
|
||||||
private urlHelper: AddonModUrlHelperProvider, private mimeUtils: CoreMimetypeUtilsProvider,
|
protected urlProvider: AddonModUrlProvider,
|
||||||
private sitesProvider: CoreSitesProvider) {
|
protected urlHelper: AddonModUrlHelperProvider,
|
||||||
|
protected mimeUtils: CoreMimetypeUtilsProvider) {
|
||||||
super(injector);
|
super(injector);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,12 +14,7 @@
|
||||||
|
|
||||||
import { Injector, Input, NgZone } from '@angular/core';
|
import { Injector, Input, NgZone } from '@angular/core';
|
||||||
import { Content } from 'ionic-angular';
|
import { Content } from 'ionic-angular';
|
||||||
import { CoreSitesProvider } from '@providers/sites';
|
|
||||||
import { CoreCourseProvider } from '@core/course/providers/course';
|
|
||||||
import { CoreCourseModulePrefetchDelegate } from '@core/course/providers/module-prefetch-delegate';
|
|
||||||
import { CoreEventsProvider } from '@providers/events';
|
|
||||||
import { Network } from '@ionic-native/network';
|
import { Network } from '@ionic-native/network';
|
||||||
import { CoreAppProvider } from '@providers/app';
|
|
||||||
import { CoreCourseModuleMainResourceComponent } from './main-resource-component';
|
import { CoreCourseModuleMainResourceComponent } from './main-resource-component';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -35,30 +30,13 @@ export class CoreCourseModuleMainActivityComponent extends CoreCourseModuleMainR
|
||||||
hasOffline: boolean; // If it has offline data to be synced.
|
hasOffline: boolean; // If it has offline data to be synced.
|
||||||
isOnline: boolean; // If the app is online or not.
|
isOnline: boolean; // If the app is online or not.
|
||||||
|
|
||||||
protected siteId: string; // Current Site ID.
|
|
||||||
protected syncObserver: any; // It will observe the sync auto event.
|
protected syncObserver: any; // It will observe the sync auto event.
|
||||||
protected statusObserver: any; // It will observe changes on the status of the activity. Only if setStatusListener is called.
|
|
||||||
protected onlineObserver: any; // It will observe the status of the network connection.
|
protected onlineObserver: any; // It will observe the status of the network connection.
|
||||||
protected syncEventName: string; // Auto sync event name.
|
protected syncEventName: string; // Auto sync event name.
|
||||||
protected currentStatus: string; // The current status of the activity. Only if setStatusListener is called.
|
|
||||||
|
|
||||||
// List of services that will be injected using injector.
|
|
||||||
// It's done like this so subclasses don't have to send all the services to the parent in the constructor.
|
|
||||||
protected sitesProvider: CoreSitesProvider;
|
|
||||||
protected courseProvider: CoreCourseProvider;
|
|
||||||
protected appProvider: CoreAppProvider;
|
|
||||||
protected eventsProvider: CoreEventsProvider;
|
|
||||||
protected modulePrefetchDelegate: CoreCourseModulePrefetchDelegate;
|
|
||||||
|
|
||||||
constructor(injector: Injector, protected content?: Content, loggerName: string = 'CoreCourseModuleMainResourceComponent') {
|
constructor(injector: Injector, protected content?: Content, loggerName: string = 'CoreCourseModuleMainResourceComponent') {
|
||||||
super(injector, loggerName);
|
super(injector, loggerName);
|
||||||
|
|
||||||
this.sitesProvider = injector.get(CoreSitesProvider);
|
|
||||||
this.courseProvider = injector.get(CoreCourseProvider);
|
|
||||||
this.appProvider = injector.get(CoreAppProvider);
|
|
||||||
this.eventsProvider = injector.get(CoreEventsProvider);
|
|
||||||
this.modulePrefetchDelegate = injector.get(CoreCourseModulePrefetchDelegate);
|
|
||||||
|
|
||||||
const network = injector.get(Network);
|
const network = injector.get(Network);
|
||||||
const zone = injector.get(NgZone);
|
const zone = injector.get(NgZone);
|
||||||
|
|
||||||
|
@ -79,7 +57,6 @@ export class CoreCourseModuleMainActivityComponent extends CoreCourseModuleMainR
|
||||||
|
|
||||||
this.hasOffline = false;
|
this.hasOffline = false;
|
||||||
this.syncIcon = 'spinner';
|
this.syncIcon = 'spinner';
|
||||||
this.siteId = this.sitesProvider.getCurrentSiteId();
|
|
||||||
this.moduleName = this.courseProvider.translateModuleName(this.moduleName);
|
this.moduleName = this.courseProvider.translateModuleName(this.moduleName);
|
||||||
|
|
||||||
if (this.syncEventName) {
|
if (this.syncEventName) {
|
||||||
|
@ -242,44 +219,6 @@ export class CoreCourseModuleMainActivityComponent extends CoreCourseModuleMainR
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Displays some data based on the current status.
|
|
||||||
*
|
|
||||||
* @param status The current status.
|
|
||||||
* @param previousStatus The previous status. If not defined, there is no previous status.
|
|
||||||
*/
|
|
||||||
protected showStatus(status: string, previousStatus?: string): void {
|
|
||||||
// To be overridden.
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Watch for changes on the status.
|
|
||||||
*
|
|
||||||
* @return Promise resolved when done.
|
|
||||||
*/
|
|
||||||
protected setStatusListener(): Promise<any> {
|
|
||||||
if (typeof this.statusObserver == 'undefined') {
|
|
||||||
// Listen for changes on this module status.
|
|
||||||
this.statusObserver = this.eventsProvider.on(CoreEventsProvider.PACKAGE_STATUS_CHANGED, (data) => {
|
|
||||||
if (data.componentId === this.module.id && data.component === this.component) {
|
|
||||||
// The status has changed, update it.
|
|
||||||
const previousStatus = this.currentStatus;
|
|
||||||
this.currentStatus = data.status;
|
|
||||||
|
|
||||||
this.showStatus(this.currentStatus, previousStatus);
|
|
||||||
}
|
|
||||||
}, this.siteId);
|
|
||||||
|
|
||||||
// Also, get the current status.
|
|
||||||
return this.modulePrefetchDelegate.getModuleStatus(this.module, this.courseId).then((status) => {
|
|
||||||
this.currentStatus = status;
|
|
||||||
this.showStatus(status);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return Promise.resolve();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Performs the sync of the activity.
|
* Performs the sync of the activity.
|
||||||
*
|
*
|
||||||
|
@ -329,6 +268,5 @@ export class CoreCourseModuleMainActivityComponent extends CoreCourseModuleMainR
|
||||||
|
|
||||||
this.onlineObserver && this.onlineObserver.unsubscribe();
|
this.onlineObserver && this.onlineObserver.unsubscribe();
|
||||||
this.syncObserver && this.syncObserver.off();
|
this.syncObserver && this.syncObserver.off();
|
||||||
this.statusObserver && this.statusObserver.off();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,16 +15,29 @@
|
||||||
import { OnInit, OnDestroy, Input, Output, EventEmitter, Injector } from '@angular/core';
|
import { OnInit, OnDestroy, Input, Output, EventEmitter, Injector } from '@angular/core';
|
||||||
import { NavController } from 'ionic-angular';
|
import { NavController } from 'ionic-angular';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
|
import { CoreAppProvider } from '@providers/app';
|
||||||
|
import { CoreEventsProvider } from '@providers/events';
|
||||||
import { CoreLoggerProvider } from '@providers/logger';
|
import { CoreLoggerProvider } from '@providers/logger';
|
||||||
|
import { CoreSitesProvider } from '@providers/sites';
|
||||||
import { CoreDomUtilsProvider } from '@providers/utils/dom';
|
import { CoreDomUtilsProvider } from '@providers/utils/dom';
|
||||||
import { CoreTextUtilsProvider, CoreTextErrorObject } from '@providers/utils/text';
|
import { CoreTextUtilsProvider, CoreTextErrorObject } from '@providers/utils/text';
|
||||||
import { CoreCourseHelperProvider } from '@core/course/providers/helper';
|
import { CoreCourseHelperProvider } from '@core/course/providers/helper';
|
||||||
|
import { CoreCourseProvider } from '@core/course/providers/course';
|
||||||
import { CoreCourseModuleMainComponent, CoreCourseModuleDelegate } from '@core/course/providers/module-delegate';
|
import { CoreCourseModuleMainComponent, CoreCourseModuleDelegate } from '@core/course/providers/module-delegate';
|
||||||
|
import { CoreCourseModulePrefetchDelegate } from '@core/course/providers/module-prefetch-delegate';
|
||||||
import { CoreCourseSectionPage } from '@core/course/pages/section/section.ts';
|
import { CoreCourseSectionPage } from '@core/course/pages/section/section.ts';
|
||||||
import { CoreContentLinksHelperProvider } from '@core/contentlinks/providers/helper';
|
import { CoreContentLinksHelperProvider } from '@core/contentlinks/providers/helper';
|
||||||
import { AddonBlogProvider } from '@addon/blog/providers/blog';
|
import { AddonBlogProvider } from '@addon/blog/providers/blog';
|
||||||
import { CoreConstants } from '@core/constants';
|
import { CoreConstants } from '@core/constants';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Result of a resource download.
|
||||||
|
*/
|
||||||
|
export type CoreCourseResourceDownloadResult = {
|
||||||
|
failed?: boolean; // Whether the download has failed.
|
||||||
|
error?: string | CoreTextErrorObject; // The error in case it failed.
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Template class to easily create CoreCourseModuleMainComponent of resources (or activities without syncing).
|
* Template class to easily create CoreCourseModuleMainComponent of resources (or activities without syncing).
|
||||||
*/
|
*/
|
||||||
|
@ -52,6 +65,9 @@ export class CoreCourseModuleMainResourceComponent implements OnInit, OnDestroy,
|
||||||
protected contextFileStatusObserver; // Observer of file status changed, used when calling fillContextMenu.
|
protected contextFileStatusObserver; // Observer of file status changed, used when calling fillContextMenu.
|
||||||
protected fetchContentDefaultError = 'core.course.errorgetmodule'; // Default error to show when loading contents.
|
protected fetchContentDefaultError = 'core.course.errorgetmodule'; // Default error to show when loading contents.
|
||||||
protected isCurrentView: boolean; // Whether the component is in the current view.
|
protected isCurrentView: boolean; // Whether the component is in the current view.
|
||||||
|
protected siteId: string; // Current Site ID.
|
||||||
|
protected statusObserver: any; // It will observe changes on the status of the module. Only if setStatusListener is called.
|
||||||
|
protected currentStatus: string; // The current status of the module. Only if setStatusListener is called.
|
||||||
|
|
||||||
// List of services that will be injected using injector.
|
// List of services that will be injected using injector.
|
||||||
// It's done like this so subclasses don't have to send all the services to the parent in the constructor.
|
// It's done like this so subclasses don't have to send all the services to the parent in the constructor.
|
||||||
|
@ -64,6 +80,11 @@ export class CoreCourseModuleMainResourceComponent implements OnInit, OnDestroy,
|
||||||
protected linkHelper: CoreContentLinksHelperProvider;
|
protected linkHelper: CoreContentLinksHelperProvider;
|
||||||
protected navCtrl: NavController;
|
protected navCtrl: NavController;
|
||||||
protected blogProvider: AddonBlogProvider;
|
protected blogProvider: AddonBlogProvider;
|
||||||
|
protected sitesProvider: CoreSitesProvider;
|
||||||
|
protected eventsProvider: CoreEventsProvider;
|
||||||
|
protected modulePrefetchDelegate: CoreCourseModulePrefetchDelegate;
|
||||||
|
protected courseProvider: CoreCourseProvider;
|
||||||
|
protected appProvider: CoreAppProvider;
|
||||||
|
|
||||||
protected logger;
|
protected logger;
|
||||||
|
|
||||||
|
@ -77,6 +98,12 @@ export class CoreCourseModuleMainResourceComponent implements OnInit, OnDestroy,
|
||||||
this.linkHelper = injector.get(CoreContentLinksHelperProvider);
|
this.linkHelper = injector.get(CoreContentLinksHelperProvider);
|
||||||
this.navCtrl = injector.get(NavController, null);
|
this.navCtrl = injector.get(NavController, null);
|
||||||
this.blogProvider = injector.get(AddonBlogProvider, null);
|
this.blogProvider = injector.get(AddonBlogProvider, null);
|
||||||
|
this.sitesProvider = injector.get(CoreSitesProvider);
|
||||||
|
this.eventsProvider = injector.get(CoreEventsProvider);
|
||||||
|
this.modulePrefetchDelegate = injector.get(CoreCourseModulePrefetchDelegate);
|
||||||
|
this.courseProvider = injector.get(CoreCourseProvider);
|
||||||
|
this.appProvider = injector.get(CoreAppProvider);
|
||||||
|
|
||||||
this.dataRetrieved = new EventEmitter();
|
this.dataRetrieved = new EventEmitter();
|
||||||
|
|
||||||
const loggerProvider = injector.get(CoreLoggerProvider);
|
const loggerProvider = injector.get(CoreLoggerProvider);
|
||||||
|
@ -87,6 +114,7 @@ export class CoreCourseModuleMainResourceComponent implements OnInit, OnDestroy,
|
||||||
* Component being initialized.
|
* Component being initialized.
|
||||||
*/
|
*/
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
|
this.siteId = this.sitesProvider.getCurrentSiteId();
|
||||||
this.description = this.module.description;
|
this.description = this.module.description;
|
||||||
this.componentId = this.module.id;
|
this.componentId = this.module.id;
|
||||||
this.externalUrl = this.module.url;
|
this.externalUrl = this.module.url;
|
||||||
|
@ -274,18 +302,122 @@ export class CoreCourseModuleMainResourceComponent implements OnInit, OnDestroy,
|
||||||
this.courseHelper.confirmAndRemoveFiles(this.module, this.courseId, done);
|
this.courseHelper.confirmAndRemoveFiles(this.module, this.courseId, done);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get message about an error occurred while downloading files.
|
||||||
|
*
|
||||||
|
* @param error The specific error.
|
||||||
|
* @param multiLine Whether to put each message in a different paragraph or in a single line.
|
||||||
|
*/
|
||||||
|
protected getErrorDownloadingSomeFilesMessage(error: string | CoreTextErrorObject, multiLine?: boolean): string {
|
||||||
|
if (multiLine) {
|
||||||
|
return this.textUtils.buildSeveralParagraphsMessage([
|
||||||
|
this.translate.instant('core.errordownloadingsomefiles'),
|
||||||
|
error,
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
error = this.textUtils.getErrorMessageFromError(error);
|
||||||
|
|
||||||
|
return this.translate.instant('core.errordownloadingsomefiles') + (error ? ' ' + error : '');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show an error occurred while downloading files.
|
* Show an error occurred while downloading files.
|
||||||
*
|
*
|
||||||
* @param error The specific error.
|
* @param error The specific error.
|
||||||
*/
|
*/
|
||||||
protected showErrorDownloadingSomeFiles(error: string | CoreTextErrorObject): void {
|
protected showErrorDownloadingSomeFiles(error: string | CoreTextErrorObject): void {
|
||||||
const errorMessage = this.textUtils.buildSeveralParagraphsMessage([
|
this.domUtils.showErrorModal(this.getErrorDownloadingSomeFilesMessage(error, true));
|
||||||
this.translate.instant('core.errordownloadingsomefiles'),
|
}
|
||||||
error,
|
|
||||||
]);
|
|
||||||
|
|
||||||
this.domUtils.showErrorModal(errorMessage);
|
/**
|
||||||
|
* Displays some data based on the current status.
|
||||||
|
*
|
||||||
|
* @param status The current status.
|
||||||
|
* @param previousStatus The previous status. If not defined, there is no previous status.
|
||||||
|
*/
|
||||||
|
protected showStatus(status: string, previousStatus?: string): void {
|
||||||
|
// To be overridden.
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Watch for changes on the status.
|
||||||
|
*
|
||||||
|
* @return Promise resolved when done.
|
||||||
|
*/
|
||||||
|
protected setStatusListener(): Promise<any> {
|
||||||
|
if (typeof this.statusObserver == 'undefined') {
|
||||||
|
// Listen for changes on this module status.
|
||||||
|
this.statusObserver = this.eventsProvider.on(CoreEventsProvider.PACKAGE_STATUS_CHANGED, (data) => {
|
||||||
|
if (data.componentId === this.module.id && data.component === this.component) {
|
||||||
|
// The status has changed, update it.
|
||||||
|
const previousStatus = this.currentStatus;
|
||||||
|
this.currentStatus = data.status;
|
||||||
|
|
||||||
|
this.showStatus(this.currentStatus, previousStatus);
|
||||||
|
}
|
||||||
|
}, this.siteId);
|
||||||
|
|
||||||
|
// Also, get the current status.
|
||||||
|
return this.modulePrefetchDelegate.getModuleStatus(this.module, this.courseId).then((status) => {
|
||||||
|
this.currentStatus = status;
|
||||||
|
this.showStatus(status);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Download a resource if needed.
|
||||||
|
* If the download call fails the promise won't be rejected, but the error will be included in the returned object.
|
||||||
|
* If module.contents cannot be loaded then the Promise will be rejected.
|
||||||
|
*
|
||||||
|
* @param refresh Whether we're refreshing data.
|
||||||
|
* @return Promise resolved when done.
|
||||||
|
*/
|
||||||
|
protected async downloadResourceIfNeeded(refresh?: boolean, contentsAlreadyLoaded?: boolean)
|
||||||
|
: Promise<CoreCourseResourceDownloadResult> {
|
||||||
|
|
||||||
|
const result: CoreCourseResourceDownloadResult = {
|
||||||
|
failed: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Get module status to determine if it needs to be downloaded.
|
||||||
|
await this.setStatusListener();
|
||||||
|
|
||||||
|
if (this.currentStatus != CoreConstants.DOWNLOADED) {
|
||||||
|
// Download content. This function also loads module contents if needed.
|
||||||
|
try {
|
||||||
|
await this.modulePrefetchDelegate.downloadModule(this.module, this.courseId);
|
||||||
|
|
||||||
|
// If we reach here it means the download process already loaded the contents, no need to do it again.
|
||||||
|
contentsAlreadyLoaded = true;
|
||||||
|
} catch (error) {
|
||||||
|
// Mark download as failed but go on since the main files could have been downloaded.
|
||||||
|
result.failed = true;
|
||||||
|
result.error = error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.module.contents.length || (refresh && !contentsAlreadyLoaded)) {
|
||||||
|
// Try to load the contents.
|
||||||
|
const ignoreCache = refresh && this.appProvider.isOnline();
|
||||||
|
|
||||||
|
try {
|
||||||
|
await this.courseProvider.loadModuleContents(this.module, this.courseId, undefined, false, ignoreCache);
|
||||||
|
} catch (error) {
|
||||||
|
// Error loading contents. If we ignored cache, try to get the cached value.
|
||||||
|
if (ignoreCache && !this.module.contents) {
|
||||||
|
await this.courseProvider.loadModuleContents(this.module, this.courseId);
|
||||||
|
} else if (!this.module.contents) {
|
||||||
|
// Not able to load contents, throw the error.
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -295,6 +427,7 @@ export class CoreCourseModuleMainResourceComponent implements OnInit, OnDestroy,
|
||||||
this.isDestroyed = true;
|
this.isDestroyed = true;
|
||||||
this.contextMenuStatusObserver && this.contextMenuStatusObserver.off();
|
this.contextMenuStatusObserver && this.contextMenuStatusObserver.off();
|
||||||
this.contextFileStatusObserver && this.contextFileStatusObserver.off();
|
this.contextFileStatusObserver && this.contextFileStatusObserver.off();
|
||||||
|
this.statusObserver && this.statusObserver.off();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -404,6 +404,25 @@ export class CoreCourseModulePrefetchDelegate extends CoreDelegate {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Download a module.
|
||||||
|
*
|
||||||
|
* @param module Module to download.
|
||||||
|
* @param courseId Course ID the module belongs to.
|
||||||
|
* @param dirPath Path of the directory where to store all the content files.
|
||||||
|
* @return Promise resolved when finished.
|
||||||
|
*/
|
||||||
|
async downloadModule(module: any, courseId: number, dirPath?: string): Promise<void> {
|
||||||
|
const handler = this.getPrefetchHandlerFor(module);
|
||||||
|
|
||||||
|
// Check if the module has a prefetch handler.
|
||||||
|
if (handler) {
|
||||||
|
await this.syncModule(module, courseId);
|
||||||
|
|
||||||
|
await handler.download(module, courseId, dirPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check for updates in a course.
|
* Check for updates in a course.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue