diff --git a/src/core/features/course/components/module-description/module-description.ts b/src/core/features/course/components/module-description/module-description.ts
index 6fc2ed236..3fdb7dacb 100644
--- a/src/core/features/course/components/module-description/module-description.ts
+++ b/src/core/features/course/components/module-description/module-description.ts
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import { Component, Input } from '@angular/core';
+import { Component, HostBinding, Input } from '@angular/core';
/**
* Component to display the description of a module.
@@ -47,4 +47,8 @@ export class CoreCourseModuleDescriptionComponent {
@Input() contextInstanceId?: number; // The instance ID related to the context.
@Input() courseId?: number; // Course ID the text belongs to. It can be used to improve performance with filters.
+ @HostBinding('class.deprecated') get isDeprecated(): boolean {
+ return true;
+ };
+
}
diff --git a/src/core/features/courses/components/course-progress/core-courses-course-progress.html b/src/core/features/courses/components/course-progress/core-courses-course-progress.html
index df6910ac0..9e0388ac8 100644
--- a/src/core/features/courses/components/course-progress/core-courses-course-progress.html
+++ b/src/core/features/courses/components/course-progress/core-courses-course-progress.html
@@ -1,60 +1,3 @@
-
-
-
-
-
- = 0 && completionUserTracked !== false" class="core-course-progress">
-
-
-
-
-
+
+
diff --git a/src/core/features/courses/components/course-progress/course-progress.scss b/src/core/features/courses/components/course-progress/course-progress.scss
deleted file mode 100644
index b8749c358..000000000
--- a/src/core/features/courses/components/course-progress/course-progress.scss
+++ /dev/null
@@ -1,159 +0,0 @@
-@import "~theme/globals";
-
-:host {
- ion-card {
- --vertical-margin: 12px;
-
- display: flex;
- flex-direction: column;
- align-self: stretch;
- height: calc(100% - var(--vertical-margin) - var(--vertical-margin));
- margin-top: var(--vertical-margin);
- margin-bottom: var(--vertical-margin);
-
- @for $i from 0 to length($core-course-image-background) {
- &[course-color="#{$i}"] .core-course-thumb {
- background: var(--core-course-color-#{$i});
- }
- }
-
- .core-course-thumb {
- padding-top: 40%;
- width: 100%;
- overflow: hidden;
- cursor: pointer;
- pointer-events: auto;
- position: relative;
- background-position: center;
- background-size: cover;
- -webkit-transition: all 50ms ease-in-out;
- transition: all 50ms ease-in-out;
-
- &.core-course-color-img {
- background: var(--ion-item-background);
- }
-
- img {
- position: absolute;
- top: 0;
- bottom: 0;
- right: 0;
- left: 0;
- margin: auto;
-
- // Fill geopaterns
- &[src$=".svg"] {
- min-width: 100%;
- }
- }
- }
-
- @if ($core-course-hide-thumb-on-cards) {
- .core-course-thumb {
- display: none;
- }
- }
-
- @if ($core-course-thumb-on-cards-background) {
- .core-course-thumb {
- background: $core-course-thumb-on-cards-background !important;
- }
- }
-
- .core-course-additional-info {
- margin-bottom: 8px;
- }
-
- .core-course-header {
- flex-grow: 1;
- display: flex;
- flex-direction: column;
-
- &.core-course-only-title {
- &::part(native) {
- flex-grow: 1;
- }
-
- }
-
- .core-course-title {
- margin: 12px 0;
- flex-grow: 1;
-
- .item-heading ion-icon {
- margin-right: 4px;
- color: var(--core-star-color);
- }
- }
-
- .core-button-spinner {
- margin: 0;
- }
- .core-button-spinner ion-spinner {
- vertical-align: top; // the better option for most scenarios
- vertical-align: -webkit-baseline-middle; // the best for those that support it
- }
-
- .core-button-spinner .core-icon-downloaded {
- font-size: 28.8px;
- margin-top: 8px;
- vertical-align: top;
- }
-
- .item-button[icon-only] {
- min-width: 50px;
- width: 50px;
- }
- }
-
- @if ($core-course-hide-progress-on-cards) {
- .core-course-progress {
- display: none;
- }
- }
- }
-
- button {
- z-index: 1;
- }
-}
-
-// Common styles.
-:host-context(.core-horizontal-scroll) {
- @include horizontal_scroll_item(80%, 250px, 300px);
-
- ion-card {
- .core-course-thumb {
- padding-top: 30%;
- }
-
- .core-course-header {
- .core-course-title {
- margin: 7px 0;
-
- .item-heading ion-icon {
- margin-right: 2px;
- }
-
- &.core-course-with-buttons {
- max-width: calc(100% - 40px);
- }
- }
- .core-button-spinner {
- min-height: 40px;
- min-width: 40px;
-
- ion-spinner {
- width: 20px;
- height: 20px;
- }
- }
- .item-button[icon-only] {
- min-width: 40px;
- width: 40px;
- padding: 8px;
- }
-
- }
- }
-}
diff --git a/src/core/features/courses/components/course-progress/course-progress.ts b/src/core/features/courses/components/course-progress/course-progress.ts
index 5d57483d3..8a415da17 100644
--- a/src/core/features/courses/components/course-progress/course-progress.ts
+++ b/src/core/features/courses/components/course-progress/course-progress.ts
@@ -12,21 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import { Component, Input, OnInit, OnDestroy, OnChanges } from '@angular/core';
-import { CoreEventCourseStatusChanged, CoreEventObserver, CoreEvents } from '@singletons/events';
-import { CoreSites } from '@services/sites';
-import { CoreDomUtils } from '@services/utils/dom';
-import { CoreCourses, CoreCoursesProvider } from '@features/courses/services/courses';
-import { CoreCourse, CoreCourseProvider } from '@features/course/services/course';
-import { CoreCourseHelper, CorePrefetchStatusInfo } from '@features/course/services/course-helper';
-import { Translate } from '@singletons';
-import { CoreConstants } from '@/core/constants';
-import {
- CoreCourseAnyCourseDataWithExtraInfoAndOptions,
- CoreEnrolledCourseDataWithExtraInfoAndOptions,
-} from '../../services/courses-helper';
-import { CoreCoursesCourseOptionsMenuComponent } from '../course-options-menu/course-options-menu';
-import { CoreUser } from '@features/user/services/user';
+import { Component, HostBinding, Input } from '@angular/core';
+import { CoreCourseListItem } from '@features/courses/services/courses';
/**
* This component is meant to display a course for a list of courses with progress.
@@ -41,296 +28,15 @@ import { CoreUser } from '@features/user/services/user';
@Component({
selector: 'core-courses-course-progress',
templateUrl: 'core-courses-course-progress.html',
- styleUrls: ['course-progress.scss'],
})
-export class CoreCoursesCourseProgressComponent implements OnInit, OnDestroy, OnChanges {
+export class CoreCoursesCourseProgressComponent {
- // The course to render.
- @Input() course!: CoreCourseAnyCourseDataWithExtraInfoAndOptions;
+ @Input() course!: CoreCourseListItem; // The course to render.
@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.
- prefetchCourseData: CorePrefetchStatusInfo = {
- icon: '',
- statusTranslatable: 'core.loading',
- status: '',
- loading: true,
+ @HostBinding('class.deprecated') get isDeprecated(): boolean {
+ return true;
};
- showSpinner = false;
- downloadCourseEnabled = false;
- courseOptionMenuEnabled = false;
- isFavourite = false;
- progress = -1;
- completionUserTracked: boolean | undefined = false;
-
- protected courseStatus = CoreConstants.NOT_DOWNLOADED;
- protected isDestroyed = false;
- protected courseStatusObserver?: CoreEventObserver;
- protected siteUpdatedObserver?: CoreEventObserver;
-
- /**
- * @inheritdoc
- */
- ngOnInit(): void {
-
- this.downloadCourseEnabled = !CoreCourses.isDownloadCourseDisabledInSite();
-
- if (this.downloadCourseEnabled) {
- this.initPrefetchCourse();
- }
-
- // This field is only available from 3.6 onwards.
- this.courseOptionMenuEnabled = this.showAll && 'isfavourite' in this.course &&
- this.course.isfavourite !== undefined;
-
- // Refresh the enabled flag if site is updated.
- this.siteUpdatedObserver = CoreEvents.on(CoreEvents.SITE_UPDATED, () => {
- const wasEnabled = this.downloadCourseEnabled;
-
- this.downloadCourseEnabled = !CoreCourses.isDownloadCourseDisabledInSite();
-
- if (!wasEnabled && this.downloadCourseEnabled) {
- // Download course is enabled now, initialize it.
- this.initPrefetchCourse();
- }
- }, CoreSites.getCurrentSiteId());
- }
-
- /**
- * @inheritdoc
- */
- ngOnChanges(): void {
- this.isFavourite = 'isfavourite' in this.course && !!this.course.isfavourite;
- this.progress = 'progress' in this.course ? this.course.progress || -1 : -1;
- this.completionUserTracked = 'completionusertracked' in this.course && this.course.completionusertracked;
- }
-
- /**
- * Initialize prefetch course.
- */
- async initPrefetchCourse(): Promise {
- if (this.courseStatusObserver !== undefined) {
- // Already initialized.
- return;
- }
-
- // Listen for status change in course.
- this.courseStatusObserver = CoreEvents.on(CoreEvents.COURSE_STATUS_CHANGED, (data: CoreEventCourseStatusChanged) => {
- if (data.courseId == this.course.id || data.courseId == CoreCourseProvider.ALL_COURSES_CLEARED) {
- this.updateCourseStatus(data.status);
- }
- }, CoreSites.getCurrentSiteId());
-
- // Determine course prefetch icon.
- const status = await CoreCourse.getCourseStatus(this.course.id);
-
- this.updateCourseStatus(status);
-
- if (this.prefetchCourseData.loading) {
- // Course is being downloaded. Get the download promise.
- const promise = CoreCourseHelper.getCourseDownloadPromise(this.course.id);
- if (promise) {
- // There is a download promise. If it fails, show an error.
- promise.catch((error) => {
- if (!this.isDestroyed) {
- CoreDomUtils.showErrorModalDefault(error, 'core.course.errordownloadingcourse', true);
- }
- });
- } else {
- // No download, this probably means that the app was closed while downloading. Set previous status.
- CoreCourse.setCoursePreviousStatus(this.course.id);
- }
- }
-
- }
-
- /**
- * Open a course.
- */
- openCourse(): void {
- CoreCourseHelper.openCourse(this.course);
- }
-
- /**
- * Prefetch the course.
- *
- * @param e Click event.
- */
- async prefetchCourse(e?: Event): Promise {
- e?.preventDefault();
- e?.stopPropagation();
-
- try {
- await CoreCourseHelper.confirmAndPrefetchCourse(this.prefetchCourseData, this.course);
- } catch (error) {
- if (!this.isDestroyed) {
- CoreDomUtils.showErrorModalDefault(error, 'core.course.errordownloadingcourse', true);
- }
- }
- }
-
- /**
- * Delete the course.
- */
- async deleteCourse(): Promise {
- try {
- await CoreDomUtils.showDeleteConfirm(
- 'addon.storagemanager.confirmdeletedatafrom',
- { name: this.course.displayname || this.course.fullname },
- );
- } catch (error) {
- if (!CoreDomUtils.isCanceledError(error)) {
- throw error;
- }
-
- return;
- }
-
- const modal = await CoreDomUtils.showModalLoading();
-
- try {
- await CoreCourseHelper.deleteCourseFiles(this.course.id);
- } catch (error) {
- CoreDomUtils.showErrorModalDefault(error, Translate.instant('core.errordeletefile'));
- } finally {
- modal.dismiss();
- }
- }
-
- /**
- * Update the course status icon and title.
- *
- * @param status Status to show.
- */
- protected updateCourseStatus(status: string): void {
- const statusData = CoreCourseHelper.getCoursePrefetchStatusInfo(status);
-
- this.courseStatus = status;
- this.prefetchCourseData.status = statusData.status;
- this.prefetchCourseData.icon = statusData.icon;
- this.prefetchCourseData.statusTranslatable = statusData.statusTranslatable;
- this.prefetchCourseData.loading = statusData.loading;
- }
-
- /**
- * Show the context menu.
- *
- * @param e Click Event.
- */
- async showCourseOptionsMenu(e: Event): Promise {
- e.preventDefault();
- e.stopPropagation();
-
- const popoverData = await CoreDomUtils.openPopover({
- component: CoreCoursesCourseOptionsMenuComponent,
- componentProps: {
- course: this.course,
- prefetch: this.prefetchCourseData,
- },
- event: e,
- });
-
- switch (popoverData) {
- case 'download':
- if (!this.prefetchCourseData.loading) {
- this.prefetchCourse(e);
- }
- break;
- case 'delete':
- if (this.courseStatus == CoreConstants.DOWNLOADED || this.courseStatus == CoreConstants.OUTDATED) {
- this.deleteCourse();
- }
- break;
- case 'hide':
- this.setCourseHidden(true);
- break;
- case 'show':
- this.setCourseHidden(false);
- break;
- case 'favourite':
- this.setCourseFavourite(true);
- break;
- case 'unfavourite':
- this.setCourseFavourite(false);
- break;
- default:
- break;
- }
-
- }
-
- /**
- * Hide/Unhide the course from the course list.
- *
- * @param hide True to hide and false to show.
- */
- protected async setCourseHidden(hide: boolean): Promise {
- this.showSpinner = true;
-
- // We should use null to unset the preference.
- try {
- await CoreUser.updateUserPreference(
- 'block_myoverview_hidden_course_' + this.course.id,
- hide ? '1' : undefined,
- );
-
- ( this.course).hidden = hide;
- CoreEvents.trigger(CoreCoursesProvider.EVENT_MY_COURSES_UPDATED, {
- courseId: this.course.id,
- course: this.course,
- action: CoreCoursesProvider.ACTION_STATE_CHANGED,
- state: CoreCoursesProvider.STATE_HIDDEN,
- value: hide,
- }, CoreSites.getCurrentSiteId());
-
- } catch (error) {
- if (!this.isDestroyed) {
- CoreDomUtils.showErrorModalDefault(error, 'Error changing course visibility.');
- }
- } finally {
- this.showSpinner = false;
- }
- }
-
- /**
- * Favourite/Unfavourite the course from the course list.
- *
- * @param favourite True to favourite and false to unfavourite.
- */
- protected async setCourseFavourite(favourite: boolean): Promise {
- this.showSpinner = true;
-
- try {
- await CoreCourses.setFavouriteCourse(this.course.id, favourite);
-
- ( this.course).isfavourite = favourite;
- this.isFavourite = favourite;
- CoreEvents.trigger(CoreCoursesProvider.EVENT_MY_COURSES_UPDATED, {
- courseId: this.course.id,
- course: this.course,
- action: CoreCoursesProvider.ACTION_STATE_CHANGED,
- state: CoreCoursesProvider.STATE_FAVOURITE,
- value: favourite,
- }, CoreSites.getCurrentSiteId());
-
- } catch (error) {
- if (!this.isDestroyed) {
- CoreDomUtils.showErrorModalDefault(error, 'Error changing course favourite attribute.');
- }
- } finally {
- this.showSpinner = false;
- }
- }
-
- /**
- * Component destroyed.
- */
- ngOnDestroy(): void {
- this.isDestroyed = true;
-
- this.siteUpdatedObserver?.off();
- this.courseStatusObserver?.off();
- }
-
}