From 00ef0fa0a98bc77966a217ee52132463340e5107 Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Tue, 6 Feb 2018 08:43:46 +0100 Subject: [PATCH] MOBILE-2335 book: Show download button in section page --- .../mod/book/providers/module-handler.ts | 1 + .../mod/book/providers/prefetch-handler.ts | 4 +- src/core/course/components/format/format.html | 2 +- src/core/course/components/module/module.html | 20 +++- src/core/course/components/module/module.ts | 94 ++++++++++++++++++- src/core/course/providers/module-delegate.ts | 8 ++ 6 files changed, 121 insertions(+), 8 deletions(-) diff --git a/src/addon/mod/book/providers/module-handler.ts b/src/addon/mod/book/providers/module-handler.ts index 7fc1a41ac..88fc25d7e 100644 --- a/src/addon/mod/book/providers/module-handler.ts +++ b/src/addon/mod/book/providers/module-handler.ts @@ -50,6 +50,7 @@ export class AddonModBookModuleHandler implements CoreCourseModuleHandler { icon: this.courseProvider.getModuleIconSrc('book'), title: module.name, class: 'addon-mod_book-handler', + showDownloadButton: true, action(event: Event, navCtrl: NavController, module: any, courseId: number, options: NavOptions): void { navCtrl.push('AddonModBookIndexPage', {module: module, courseId: courseId}, options); } diff --git a/src/addon/mod/book/providers/prefetch-handler.ts b/src/addon/mod/book/providers/prefetch-handler.ts index 90b4fcce8..74bfd0aae 100644 --- a/src/addon/mod/book/providers/prefetch-handler.ts +++ b/src/addon/mod/book/providers/prefetch-handler.ts @@ -45,7 +45,9 @@ export class AddonModBookPrefetchHandler extends CoreCourseModulePrefetchHandler const promises = []; promises.push(super.downloadOrPrefetch(module, courseId, prefetch)); - promises.push(this.bookProvider.getBook(courseId, module.id)); + promises.push(this.bookProvider.getBook(courseId, module.id).catch(() => { + // Ignore errors since this WS isn't available in some Moodle versions. + })); return Promise.all(promises); } diff --git a/src/core/course/components/format/format.html b/src/core/course/components/format/format.html index 0b1e8dcc8..80df9237c 100644 --- a/src/core/course/components/format/format.html +++ b/src/core/course/components/format/format.html @@ -56,7 +56,7 @@ - + diff --git a/src/core/course/components/module/module.html b/src/core/course/components/module/module.html index 90fc35bb4..d4d63e0e7 100644 --- a/src/core/course/components/module/module.html +++ b/src/core/course/components/module/module.html @@ -4,14 +4,28 @@ -
+ +
+ - + + + + + + - + +
diff --git a/src/core/course/components/module/module.ts b/src/core/course/components/module/module.ts index b450093b1..15a66286b 100644 --- a/src/core/course/components/module/module.ts +++ b/src/core/course/components/module/module.ts @@ -12,9 +12,15 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { Component, Input, Output, EventEmitter, OnInit } from '@angular/core'; +import { Component, Input, Output, EventEmitter, OnInit, OnDestroy } from '@angular/core'; import { NavController } from 'ionic-angular'; +import { CoreEventsProvider } from '../../../../providers/events'; +import { CoreSitesProvider } from '../../../../providers/sites'; +import { CoreDomUtilsProvider } from '../../../../providers/utils/dom'; +import { CoreCourseHelperProvider } from '../../providers/helper'; import { CoreCourseModuleHandlerButton } from '../../providers/module-delegate'; +import { CoreCourseModulePrefetchDelegate, CoreCourseModulePrefetchHandler } from '../../providers/module-prefetch-delegate'; +import { CoreConstants } from '../../../constants'; /** * Component to display a module entry in a list of modules. @@ -27,12 +33,43 @@ import { CoreCourseModuleHandlerButton } from '../../providers/module-delegate'; selector: 'core-course-module', templateUrl: 'module.html' }) -export class CoreCourseModuleComponent implements OnInit { +export class CoreCourseModuleComponent implements OnInit, OnDestroy { @Input() module: any; // The module to render. @Input() courseId: number; // The course the module belongs to. + @Input('downloadEnabled') set enabled(value: boolean) { + this.downloadEnabled = value; + + if (this.module.handlerData.showDownloadButton && this.downloadEnabled && !this.statusObserver) { + // First time that the download is enabled. Initialize the data. + this.spinner = true; // Show spinner while calculating the status. + + this.prefetchHandler = this.prefetchDelegate.getPrefetchHandlerFor(this.module); + + // Get current status to decide which icon should be shown. + this.prefetchDelegate.getModuleStatus(this.module, this.courseId).then(this.showStatus.bind(this)); + + // Listen for changes on this module status. + this.statusObserver = this.eventsProvider.on(CoreEventsProvider.PACKAGE_STATUS_CHANGED, (data) => { + if (data.componentId === this.module.id && this.prefetchHandler && + data.component === this.prefetchHandler.component) { + this.showStatus(data.status); + } + }, this.sitesProvider.getCurrentSiteId()); + } + } @Output() completionChanged?: EventEmitter; // Will emit an event when the module completion changes. - constructor(private navCtrl: NavController) { + showDownload: boolean; // Whether to display the download button. + showRefresh: boolean; // Whether to display the refresh button. + spinner: boolean; // Whether to display a spinner. + downloadEnabled: boolean; // Whether the download of sections and modules is enabled. + + protected prefetchHandler: CoreCourseModulePrefetchHandler; + protected statusObserver; + + constructor(protected navCtrl: NavController, protected prefetchDelegate: CoreCourseModulePrefetchDelegate, + protected domUtils: CoreDomUtilsProvider, protected courseHelper: CoreCourseHelperProvider, + protected eventsProvider: CoreEventsProvider, protected sitesProvider: CoreSitesProvider) { this.completionChanged = new EventEmitter(); } @@ -68,4 +105,55 @@ export class CoreCourseModuleComponent implements OnInit { button.action(event, this.navCtrl, this.module, this.courseId); } } + + /** + * Download the module. + * + * @param {Event} event Click event. + * @param {boolean} refresh Whether it's refreshing. + */ + download(event: Event, refresh: boolean): void { + event.preventDefault(); + event.stopPropagation(); + + if (!this.prefetchHandler) { + return; + } + + // Show spinner since this operation might take a while. + this.spinner = true; + + // Get download size to ask for confirm if it's high. + this.prefetchHandler.getDownloadSize(module, this.courseId).then((size) => { + this.courseHelper.prefetchModule(this.prefetchHandler, this.module, size, this.courseId, refresh).catch((error) => { + // Error or cancelled. + this.spinner = false; + }); + }).catch((error) => { + // Error getting download size, hide spinner. + this.spinner = false; + this.domUtils.showErrorModalDefault(error, 'core.errordownloading', true); + }); + } + + /** + * Show download buttons according to module status. + * + * @param {string} status Module status. + */ + protected showStatus(status: string): void { + if (status) { + this.spinner = status === CoreConstants.DOWNLOADING; + this.showDownload = status === CoreConstants.NOT_DOWNLOADED; + this.showRefresh = status === CoreConstants.OUTDATED || + (!this.prefetchDelegate.canCheckUpdates() && status === CoreConstants.DOWNLOADED); + } + } + + /** + * Component destroyed. + */ + ngOnDestroy(): void { + this.statusObserver && this.statusObserver.off(); + } } diff --git a/src/core/course/providers/module-delegate.ts b/src/core/course/providers/module-delegate.ts index 1fbc7e2be..1a2e8c057 100644 --- a/src/core/course/providers/module-delegate.ts +++ b/src/core/course/providers/module-delegate.ts @@ -68,6 +68,14 @@ export interface CoreCourseModuleHandlerData { */ class?: string; + /** + * Whether to display a button to download/refresh the module if it's downloadable. + * If it's set to true, the app will show a download/refresh button when needed and will handle the download of the + * module using CoreCourseModulePrefetchDelegate. + * @type {boolean} + */ + showDownloadButton?: boolean; + /** * The buttons to display in the module item. * @type {CoreCourseModuleHandlerButton[]}