diff --git a/scripts/langindex.json b/scripts/langindex.json
index 3c7cda084..5ca395007 100644
--- a/scripts/langindex.json
+++ b/scripts/langindex.json
@@ -1176,6 +1176,7 @@
"core.course.warningmanualcompletionmodified": "local_moodlemobileapp",
"core.course.warningofflinemanualcompletiondeleted": "local_moodlemobileapp",
"core.coursedetails": "moodle",
+ "core.courses.addtofavourites": "block_myoverview",
"core.courses.allowguests": "enrol_guest",
"core.courses.availablecourses": "moodle",
"core.courses.cannotretrievemorecategories": "local_moodlemobileapp",
@@ -1201,6 +1202,7 @@
"core.courses.password": "local_moodlemobileapp",
"core.courses.paymentrequired": "moodle",
"core.courses.paypalaccepted": "enrol_paypal",
+ "core.courses.removefromfavourites": "block_myoverview",
"core.courses.search": "moodle",
"core.courses.searchcourses": "moodle",
"core.courses.searchcoursesadvice": "local_moodlemobileapp",
diff --git a/src/assets/lang/en.json b/src/assets/lang/en.json
index f9a96b969..cc1fa5926 100644
--- a/src/assets/lang/en.json
+++ b/src/assets/lang/en.json
@@ -1176,6 +1176,7 @@
"core.course.warningmanualcompletionmodified": "The manual completion of an activity was modified on the site.",
"core.course.warningofflinemanualcompletiondeleted": "Some offline manual completion of course '{{name}}' has been deleted. {{error}}",
"core.coursedetails": "Course details",
+ "core.courses.addtofavourites": "Star this course",
"core.courses.allowguests": "This course allows guest users to enter",
"core.courses.availablecourses": "Available courses",
"core.courses.cannotretrievemorecategories": "Categories deeper than level {{$a}} cannot be retrieved.",
@@ -1201,6 +1202,7 @@
"core.courses.password": "Enrolment key",
"core.courses.paymentrequired": "This course requires a payment for entry.",
"core.courses.paypalaccepted": "PayPal payments accepted",
+ "core.courses.removefromfavourites": "Unstar this course",
"core.courses.search": "Search",
"core.courses.searchcourses": "Search courses",
"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.",
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 ffe8a19dd..7be6638ba 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
@@ -1,5 +1,6 @@
-
+
+
{{ prefetch.title | translate }}
@@ -10,4 +11,12 @@
{{ 'core.courses.show' | translate }}
+
+
+ {{ 'core.courses.addtofavourites' | translate }}
+
+
+
+ {{ 'core.courses.removefromfavourites' | translate }}
+
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 55339fdfa..4dab77489 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
@@ -1,10 +1,12 @@
-
= 0)">
-
+
+
+
+
@@ -16,13 +18,13 @@
-
-
-
+
+
+
diff --git a/src/core/courses/components/course-progress/course-progress.scss b/src/core/courses/components/course-progress/course-progress.scss
index ca366793b..51c020133 100644
--- a/src/core/courses/components/course-progress/course-progress.scss
+++ b/src/core/courses/components/course-progress/course-progress.scss
@@ -1,3 +1,5 @@
+$core-star-color: $core-color !default;
+
ion-app.app-root core-courses-course-progress {
ion-card.card {
display: flex;
@@ -29,16 +31,6 @@ ion-app.app-root core-courses-course-progress {
bottom: 0;
margin: auto;
}
-
- ion-icon {
- position: absolute;
- @include position(0, null, null, 0);
- padding: 16px;
- color: $gray-darker;
- -webkit-text-stroke-width: 0.5px;
- -webkit-text-stroke-color: $gray-lighter;
- font-size: 16px;
- }
}
.core-course-link {
@@ -55,11 +47,24 @@ ion-app.app-root core-courses-course-progress {
h2 {
margins: 6px 0;
flex-grow: 1;
+
+ ion-icon {
+ margin-right: 4px;
+ color: $core-star-color;
+ }
}
&.core-course-more-than-title {
padding-bottom: 0;
}
+
+ .core-button-spinner .spinner {
+ vertical-align: middle;
+ }
+
+ .item-button[icon-only] {
+ min-width: 50px;
+ }
}
.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 09c9167c9..294c73dd8 100644
--- a/src/core/courses/components/course-progress/course-progress.ts
+++ b/src/core/courses/components/course-progress/course-progress.ts
@@ -178,7 +178,9 @@ export class CoreCoursesCourseProgressComponent implements OnInit, OnDestroy {
if (action) {
switch (action) {
case 'download':
- this.prefetchCourse(e);
+ if (this.prefetchCourseData.prefetchCourseIcon != 'spinner') {
+ this.prefetchCourse(e);
+ }
break;
case 'hide':
this.setCourseHidden(true);
@@ -186,6 +188,12 @@ export class CoreCoursesCourseProgressComponent implements OnInit, OnDestroy {
case 'show':
this.setCourseHidden(false);
break;
+ case 'favourite':
+ this.setCourseFavourite(true);
+ break;
+ case 'unfavourite':
+ this.setCourseFavourite(false);
+ break;
default:
break;
}
@@ -214,6 +222,23 @@ export class CoreCoursesCourseProgressComponent implements OnInit, OnDestroy {
});
}
+ /**
+ * Favourite/Unfavourite the course from the course list.
+ *
+ * @param {boolean} favourite True to favourite and false to unfavourite.
+ */
+ protected setCourseFavourite(favourite: boolean): void {
+ this.showSpinner = true;
+
+ this.coursesProvider.setFavouriteCourse(this.course.id, favourite).then(() => {
+ this.course.isfavourite = favourite;
+ 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 818098e23..e2b1fca0c 100644
--- a/src/core/courses/lang/en.json
+++ b/src/core/courses/lang/en.json
@@ -1,4 +1,5 @@
{
+ "addtofavourites": "Star this course",
"allowguests": "This course allows guest users to enter",
"availablecourses": "Available courses",
"cannotretrievemorecategories": "Categories deeper than level {{$a}} cannot be retrieved.",
@@ -24,6 +25,7 @@
"password": "Enrolment key",
"paymentrequired": "This course requires a payment for entry.",
"paypalaccepted": "PayPal payments accepted",
+ "removefromfavourites": "Unstar this course",
"search": "Search",
"searchcourses": "Search 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.",
diff --git a/src/core/courses/providers/courses.ts b/src/core/courses/providers/courses.ts
index bf5345fb1..880010733 100644
--- a/src/core/courses/providers/courses.ts
+++ b/src/core/courses/providers/courses.ts
@@ -938,4 +938,27 @@ export class CoreCoursesProvider {
});
});
}
+
+ /**
+ * Set favourite property on a course.
+ *
+ * @param {number} courseId Course ID.
+ * @param {boolean} favourite If favourite or unfavourite.
+ * @param {string} [siteId] Site ID. If not defined, use current site.
+ * @return {Promise} Promise resolved when done.
+ */
+ setFavouriteCourse(courseId: number, favourite: boolean, siteId?: string): Promise {
+ return this.sitesProvider.getSite(siteId).then((site) => {
+ const params: any = {
+ courses: [
+ {
+ id: courseId,
+ favourite: favourite ? 1 : 0
+ }
+ ]
+ };
+
+ return site.write('core_course_set_favourite_courses', params);
+ });
+ }
}