diff --git a/src/addon/block/myoverview/components/myoverview/myoverview.ts b/src/addon/block/myoverview/components/myoverview/myoverview.ts index 690c590a8..7e1668566 100644 --- a/src/addon/block/myoverview/components/myoverview/myoverview.ts +++ b/src/addon/block/myoverview/components/myoverview/myoverview.ts @@ -66,6 +66,7 @@ export class AddonBlockMyOverviewComponent extends CoreBlockBaseComponent implem protected prefetchIconsInitialized = false; protected isDestroyed; protected updateSiteObserver; + protected coursesObserver; protected courseIds = []; protected fetchContentDefaultError = 'Error getting my overview data.'; @@ -96,6 +97,10 @@ export class AddonBlockMyOverviewComponent extends CoreBlockBaseComponent implem } }); + this.coursesObserver = this.eventsProvider.on(CoreCoursesProvider.EVENT_MY_COURSES_UPDATED, () => { + this.refreshContent(); + }, this.sitesProvider.getCurrentSiteId()); + this.currentSite = this.sitesProvider.getCurrentSite(); const promises = []; @@ -326,6 +331,7 @@ export class AddonBlockMyOverviewComponent extends CoreBlockBaseComponent implem */ ngOnDestroy(): void { this.isDestroyed = true; + this.coursesObserver && this.coursesObserver.off(); this.updateSiteObserver && this.updateSiteObserver.off(); } } diff --git a/src/assets/lang/en.json b/src/assets/lang/en.json index 78a3ff5f5..1b99a5363 100644 --- a/src/assets/lang/en.json +++ b/src/assets/lang/en.json @@ -1188,6 +1188,7 @@ "core.courses.errorselfenrol": "An error occurred while self enrolling.", "core.courses.filtermycourses": "Filter my courses", "core.courses.frontpage": "Front page", + "core.courses.hidecourse": "Hide from view", "core.courses.mycourses": "My courses", "core.courses.mymoodle": "Dashboard", "core.courses.nocourses": "No course information to show.", @@ -1203,6 +1204,7 @@ "core.courses.searchcoursesadvice": "You can use the search courses button to find courses to access as a guest or enrol yourself in courses that allow it.", "core.courses.selfenrolment": "Self enrolment", "core.courses.sendpaymentbutton": "Send payment via PayPal", + "core.courses.show": "Show this course", "core.courses.totalcoursesearchresults": "Total courses: {{$a}}", "core.currentdevice": "Current device", "core.datastoredoffline": "Data stored in the device because it couldn't be sent. It will be sent automatically later.", diff --git a/src/core/courses/components/components.module.ts b/src/core/courses/components/components.module.ts index 14ce35cbc..45b2671cb 100644 --- a/src/core/courses/components/components.module.ts +++ b/src/core/courses/components/components.module.ts @@ -21,11 +21,13 @@ import { CoreDirectivesModule } from '@directives/directives.module'; import { CorePipesModule } from '@pipes/pipes.module'; import { CoreCoursesCourseProgressComponent } from '../components/course-progress/course-progress'; import { CoreCoursesCourseListItemComponent } from '../components/course-list-item/course-list-item'; +import { CoreCoursesCourseOptionsMenuComponent } from '../components/course-options-menu/course-options-menu'; @NgModule({ declarations: [ CoreCoursesCourseProgressComponent, - CoreCoursesCourseListItemComponent + CoreCoursesCourseListItemComponent, + CoreCoursesCourseOptionsMenuComponent ], imports: [ CommonModule, @@ -39,7 +41,11 @@ import { CoreCoursesCourseListItemComponent } from '../components/course-list-it ], exports: [ CoreCoursesCourseProgressComponent, - CoreCoursesCourseListItemComponent + CoreCoursesCourseListItemComponent, + CoreCoursesCourseOptionsMenuComponent + ], + entryComponents: [ + CoreCoursesCourseOptionsMenuComponent ] }) export class CoreCoursesComponentsModule {} 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 new file mode 100644 index 000000000..ffe8a19dd --- /dev/null +++ b/src/core/courses/components/course-options-menu/core-courses-course-options-menu.html @@ -0,0 +1,13 @@ + + +

{{ prefetch.title | translate }}

+
+ + +

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

+
+ + +

{{ 'core.courses.show' | 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 new file mode 100644 index 000000000..a63dbedf5 --- /dev/null +++ b/src/core/courses/components/course-options-menu/course-options-menu.ts @@ -0,0 +1,51 @@ +// (C) Copyright 2015 Martin Dougiamas +// +// 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. + +import { Component, OnInit } from '@angular/core'; +import { NavParams, ViewController } from 'ionic-angular'; +import { CoreCoursesProvider } from '../../providers/courses'; + +/** + * This component is meant to display a popover with the course options. + */ +@Component({ + selector: 'core-courses-course-options-menu', + templateUrl: 'core-courses-course-options-menu.html' +}) +export class CoreCoursesCourseOptionsMenuComponent implements OnInit { + course: any; // The course. + prefetch: any; // The prefecth info. + + downloadCourseEnabled: boolean; + + constructor(navParams: NavParams, private viewCtrl: ViewController, private coursesProvider: CoreCoursesProvider) { + this.course = navParams.get('course') || {}; + this.prefetch = navParams.get('prefetch') || {}; + } + + /** + * Component being initialized. + */ + ngOnInit(): void { + this.downloadCourseEnabled = !this.coursesProvider.isDownloadCourseDisabledInSite(); + } + + /** + * Do an action over the course. + * @param {string} action Action name to take. + */ + action(action: string): void { + this.viewCtrl.dismiss(action); + } +} diff --git a/src/core/courses/components/course-progress/core-courses-course-progress.html b/src/core/courses/components/course-progress/core-courses-course-progress.html index df001f2b0..55339fdfa 100644 --- a/src/core/courses/components/course-progress/core-courses-course-progress.html +++ b/src/core/courses/components/course-progress/core-courses-course-progress.html @@ -3,10 +3,10 @@ - +

-
+
+ +
+ + + + + +

diff --git a/src/core/courses/components/course-progress/course-progress.scss b/src/core/courses/components/course-progress/course-progress.scss index e99d46143..ca366793b 100644 --- a/src/core/courses/components/course-progress/course-progress.scss +++ b/src/core/courses/components/course-progress/course-progress.scss @@ -56,6 +56,10 @@ ion-app.app-root core-courses-course-progress { margins: 6px 0; flex-grow: 1; } + + &.core-course-more-than-title { + padding-bottom: 0; + } } .label { @include margin(0, 0, 0, null); diff --git a/src/core/courses/components/course-progress/course-progress.ts b/src/core/courses/components/course-progress/course-progress.ts index 96f9b60b5..6e4ac089d 100644 --- a/src/core/courses/components/course-progress/course-progress.ts +++ b/src/core/courses/components/course-progress/course-progress.ts @@ -13,14 +13,16 @@ // limitations under the License. import { Component, Input, OnInit, OnDestroy, Optional } from '@angular/core'; -import { NavController } from 'ionic-angular'; +import { NavController, PopoverController } from 'ionic-angular'; import { CoreEventsProvider } from '@providers/events'; import { CoreSitesProvider } from '@providers/sites'; import { CoreDomUtilsProvider } from '@providers/utils/dom'; +import { CoreUserProvider } from '@core/user/providers/user'; import { CoreCoursesProvider } from '@core/courses/providers/courses'; import { CoreCourseFormatDelegate } from '@core/course/providers/format-delegate'; import { CoreCourseProvider } from '@core/course/providers/course'; import { CoreCourseHelperProvider } from '@core/course/providers/helper'; +import { CoreCoursesCourseOptionsMenuComponent } from '../course-options-menu/course-options-menu'; /** * This component is meant to display a course for a list of courses with progress. @@ -42,7 +44,9 @@ export class CoreCoursesCourseProgressComponent implements OnInit, OnDestroy { prefetchCourseIcon: 'spinner', title: 'core.course.downloadcourse' }; + showSpinner = false; downloadCourseEnabled: boolean; + courseOptionMenuEnabled: boolean; protected isDestroyed = false; protected courseStatusObserver; @@ -51,7 +55,8 @@ export class CoreCoursesCourseProgressComponent implements OnInit, OnDestroy { constructor(@Optional() private navCtrl: NavController, private courseHelper: CoreCourseHelperProvider, private courseFormatDelegate: CoreCourseFormatDelegate, private domUtils: CoreDomUtilsProvider, private courseProvider: CoreCourseProvider, private eventsProvider: CoreEventsProvider, - private sitesProvider: CoreSitesProvider, private coursesProvider: CoreCoursesProvider) { } + private sitesProvider: CoreSitesProvider, private coursesProvider: CoreCoursesProvider, + private popoverCtrl: PopoverController, private userProvider: CoreUserProvider) { } /** * Component being initialized. @@ -63,6 +68,8 @@ export class CoreCoursesCourseProgressComponent implements OnInit, OnDestroy { this.initPrefetchCourse(); } + this.courseOptionMenuEnabled = typeof this.course.isfavourite != 'undefined'; + // Refresh the enabled flag if site is updated. this.siteUpdatedObserver = this.eventsProvider.on(CoreEventsProvider.SITE_UPDATED, () => { const wasEnabled = this.downloadCourseEnabled; @@ -153,6 +160,58 @@ export class CoreCoursesCourseProgressComponent implements OnInit, OnDestroy { this.prefetchCourseData.title = statusData.title; } + /** + * Show the context menu. + * + * @param {Event} e Click Event. + */ + showCourseOptionsMenu(e: Event): void { + e.preventDefault(); + e.stopPropagation(); + + const popover = this.popoverCtrl.create(CoreCoursesCourseOptionsMenuComponent, { + course: this.course, + prefetch: this.prefetchCourseData + }); + popover.onDidDismiss((action) => { + if (action) { + switch (action) { + case 'download': + this.prefetchCourse(e); + break; + case 'hide': + this.setCourseHidden(true); + break; + case 'show': + this.setCourseHidden(false); + break; + default: + break; + } + } + }); + popover.present({ + ev: e + }); + } + + /** + * Hide/Unhide the course from the course list. + * + * @param {boolean} hide True to hide and false to show. + */ + protected setCourseHidden(hide: boolean): void { + this.showSpinner = true; + + this.userProvider.updateUserPreference('block_myoverview_hidden_course_' + this.course.id, hide ? 1 : false).then(() => { + this.course.hidden = hide; + this.eventsProvider.trigger( + CoreCoursesProvider.EVENT_MY_COURSES_UPDATED, {course: this.course}, this.sitesProvider.getCurrentSiteId()); + }).finally(() => { + this.showSpinner = false; + }); + } + /** * Component destroyed. */ diff --git a/src/core/courses/lang/en.json b/src/core/courses/lang/en.json index f961a47ef..818098e23 100644 --- a/src/core/courses/lang/en.json +++ b/src/core/courses/lang/en.json @@ -14,6 +14,7 @@ "errorselfenrol": "An error occurred while self enrolling.", "filtermycourses": "Filter my courses", "frontpage": "Front page", + "hidecourse": "Hide from view", "mycourses": "My courses", "nocourses": "No course information to show.", "nocoursesyet": "No courses in this category", @@ -28,5 +29,6 @@ "searchcoursesadvice": "You can use the search courses button to find courses to access as a guest or enrol yourself in courses that allow it.", "selfenrolment": "Self enrolment", "sendpaymentbutton": "Send payment via PayPal", + "show": "Show this course", "totalcoursesearchresults": "Total courses: {{$a}}" } \ No newline at end of file diff --git a/src/core/courses/pages/course-preview/course-preview.ts b/src/core/courses/pages/course-preview/course-preview.ts index ce2b0d7cd..51d2253e4 100644 --- a/src/core/courses/pages/course-preview/course-preview.ts +++ b/src/core/courses/pages/course-preview/course-preview.ts @@ -353,7 +353,7 @@ export class CoreCoursesCoursePreviewPage implements OnDestroy { this.refreshData().finally(() => { // My courses have been updated, trigger event. this.eventsProvider.trigger( - CoreCoursesProvider.EVENT_MY_COURSES_UPDATED, {}, this.sitesProvider.getCurrentSiteId()); + CoreCoursesProvider.EVENT_MY_COURSES_UPDATED, {course: this.course}, this.sitesProvider.getCurrentSiteId()); }); }); }).catch((error) => {