diff --git a/src/core/course/providers/helper.ts b/src/core/course/providers/helper.ts index 606e913b2..76dd85242 100644 --- a/src/core/course/providers/helper.ts +++ b/src/core/course/providers/helper.ts @@ -40,6 +40,7 @@ import { CoreSite } from '@classes/site'; import { CoreLoggerProvider } from '@providers/logger'; import * as moment from 'moment'; import { CoreFilterHelperProvider } from '@core/filter/providers/helper'; +import { CoreArray } from '@singletons/array'; /** * Prefetch info of a module. @@ -1607,4 +1608,22 @@ export class CoreCourseHelperProvider { return this.loginHelper.redirect(CoreLoginHelperProvider.OPEN_COURSE, params, siteId); } } + + /** + * Delete course files. + * + * @param courseId Course id. + * @return Promise to be resolved once the course files are deleted. + */ + async deleteCourseFiles(courseId: number): Promise { + const sections = await this.courseProvider.getSections(courseId); + const modules = CoreArray.flatten(sections.map((section) => section.modules)); + + await Promise.all( + modules.map((module) => this.prefetchDelegate.removeModuleFiles(module, courseId)), + ); + + await this.courseProvider.setCourseStatus(courseId, CoreConstants.NOT_DOWNLOADED); + } + } diff --git a/src/core/courses/components/course-options-menu/core-courses-course-options-menu.html b/src/core/courses/components/course-options-menu/core-courses-course-options-menu.html index 9e17624b8..53682fd43 100644 --- a/src/core/courses/components/course-options-menu/core-courses-course-options-menu.html +++ b/src/core/courses/components/course-options-menu/core-courses-course-options-menu.html @@ -3,6 +3,10 @@

{{ prefetch.title | translate }}

+ + +

{{ 'addon.storagemanager.deletecourse' | translate }}

+

{{ 'core.courses.hidecourse' | translate }}

diff --git a/src/core/courses/components/course-options-menu/course-options-menu.ts b/src/core/courses/components/course-options-menu/course-options-menu.ts index 02aae3630..fba1d2de2 100644 --- a/src/core/courses/components/course-options-menu/course-options-menu.ts +++ b/src/core/courses/components/course-options-menu/course-options-menu.ts @@ -15,6 +15,7 @@ import { Component, OnInit } from '@angular/core'; import { NavParams, ViewController } from 'ionic-angular'; import { CoreCoursesProvider } from '../../providers/courses'; +import { CoreConstants } from '@core/constants'; /** * This component is meant to display a popover with the course options. @@ -25,12 +26,14 @@ import { CoreCoursesProvider } from '../../providers/courses'; }) export class CoreCoursesCourseOptionsMenuComponent implements OnInit { course: any; // The course. + courseStatus: string; // The course status. prefetch: any; // The prefecth info. downloadCourseEnabled: boolean; constructor(navParams: NavParams, private viewCtrl: ViewController, private coursesProvider: CoreCoursesProvider) { this.course = navParams.get('course') || {}; + this.courseStatus = navParams.get('courseStatus') || CoreConstants.NOT_DOWNLOADED; this.prefetch = navParams.get('prefetch') || {}; } diff --git a/src/core/courses/components/course-progress/course-progress.ts b/src/core/courses/components/course-progress/course-progress.ts index cafc7c142..c0b32c4b7 100644 --- a/src/core/courses/components/course-progress/course-progress.ts +++ b/src/core/courses/components/course-progress/course-progress.ts @@ -22,6 +22,8 @@ import { CoreCoursesProvider } from '@core/courses/providers/courses'; import { CoreCourseProvider } from '@core/course/providers/course'; import { CoreCourseHelperProvider } from '@core/course/providers/helper'; import { CoreCoursesCourseOptionsMenuComponent } from '../course-options-menu/course-options-menu'; +import { Translate } from '@singletons/core.singletons'; +import { CoreConstants } from '@core/constants'; /** * This component is meant to display a course for a list of courses with progress. @@ -40,6 +42,7 @@ export class CoreCoursesCourseProgressComponent implements OnInit, OnDestroy { @Input() showAll = false; // If true, will show all actions, options, star and progress. @Input() showDownload = true; // If true, will show download button. Only works if the options menu is not shown. + courseStatus = CoreConstants.NOT_DOWNLOADED; isDownloading: boolean; prefetchCourseData = { downloadSucceeded: false, @@ -104,7 +107,10 @@ export class CoreCoursesCourseProgressComponent implements OnInit, OnDestroy { }, this.sitesProvider.getCurrentSiteId()); // Determine course prefetch icon. - this.courseHelper.getCourseStatusIconAndTitle(this.course.id).then((data) => { + this.courseProvider.getCourseStatus(this.course.id).then((status) => { + const data = this.courseHelper.getCourseStatusIconAndTitleFromStatus(status); + + this.courseStatus = status; this.prefetchCourseData.prefetchCourseIcon = data.icon; this.prefetchCourseData.title = data.title; @@ -152,6 +158,21 @@ export class CoreCoursesCourseProgressComponent implements OnInit, OnDestroy { }); } + /** + * Delete the course. + */ + async deleteCourse(): Promise { + const modal = this.domUtils.showModalLoading(); + + try { + await this.courseHelper.deleteCourseFiles(this.course.id); + } catch (error) { + this.domUtils.showErrorModalDefault(error, Translate.instance.instant('core.errordeletefile')); + } finally { + modal.dismiss(); + } + } + /** * Update the course status icon and title. * @@ -160,6 +181,7 @@ export class CoreCoursesCourseProgressComponent implements OnInit, OnDestroy { protected updateCourseStatus(status: string): void { const statusData = this.courseHelper.getCourseStatusIconAndTitleFromStatus(status); + this.courseStatus = status; this.prefetchCourseData.prefetchCourseIcon = statusData.icon; this.prefetchCourseData.title = statusData.title; } @@ -175,6 +197,7 @@ export class CoreCoursesCourseProgressComponent implements OnInit, OnDestroy { const popover = this.popoverCtrl.create(CoreCoursesCourseOptionsMenuComponent, { course: this.course, + courseStatus: this.courseStatus, prefetch: this.prefetchCourseData }); popover.onDidDismiss((action) => { @@ -185,6 +208,11 @@ export class CoreCoursesCourseProgressComponent implements OnInit, OnDestroy { this.prefetchCourse(e); } break; + case 'delete': + if (this.courseStatus == 'downloaded' || this.courseStatus == 'outdated') { + this.deleteCourse(); + } + break; case 'hide': this.setCourseHidden(true); break; diff --git a/src/singletons/array.ts b/src/singletons/array.ts new file mode 100644 index 000000000..6411c9f9a --- /dev/null +++ b/src/singletons/array.ts @@ -0,0 +1,36 @@ +// (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. + +/** + * Singleton with helper functions for arrays. + */ +export class CoreArray { + + /** + * Flatten the first dimension of a multi-dimensional array. + * + * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat#reduce_and_concat + * + * @param arr Original array. + * @return Flattened array. + */ + static flatten(arr: T[][]): T[] { + if ('flat' in arr) { + return (arr as any).flat(); + } + + return [].concat(...arr); + } + +}