MOBILE-3305: Add option to delete a downloaded course

main
Noel De Martin 2020-06-03 12:35:22 +02:00
parent 4f9adba63e
commit 16ebd1c72e
5 changed files with 91 additions and 1 deletions

View File

@ -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<void> {
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);
}
}

View File

@ -3,6 +3,10 @@
<ion-spinner *ngIf="prefetch.prefetchCourseIcon == 'spinner'" item-start></ion-spinner>
<h2>{{ prefetch.title | translate }}</h2>
</ion-item>
<ion-item text-wrap (click)="action('delete')" *ngIf="courseStatus == 'downloaded' || courseStatus == 'outdated'">
<ion-icon name="trash" item-start></ion-icon>
<h2>{{ 'addon.storagemanager.deletecourse' | translate }}</h2>
</ion-item>
<ion-item text-wrap (click)="action('hide')" *ngIf="!course.hidden">
<core-icon name="fa-eye" item-start></core-icon>
<h2>{{ 'core.courses.hidecourse' | translate }}</h2>

View File

@ -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') || {};
}

View File

@ -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<void> {
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;

View File

@ -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<T>(arr: T[][]): T[] {
if ('flat' in arr) {
return (arr as any).flat();
}
return [].concat(...arr);
}
}