MOBILE-3305: Add option to delete a downloaded course
parent
4f9adba63e
commit
16ebd1c72e
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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') || {};
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue