From e789d2628023aca744a6b3d766bdb9fc1a3f9075 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Thu, 14 Oct 2021 11:02:03 +0200 Subject: [PATCH] MOBILE-3686 courses: Fix permanency of download options setting --- .../course/pages/contents/contents.ts | 73 +++++++++++++------ .../courses/pages/categories/categories.ts | 20 ++++- .../courses/pages/dashboard/dashboard.html | 8 +- .../courses/pages/dashboard/dashboard.ts | 37 ++++++---- src/core/features/courses/pages/list/list.ts | 26 +++++-- src/core/features/courses/services/courses.ts | 32 ++++++-- .../features/sitehome/pages/index/index.html | 10 +-- .../features/sitehome/pages/index/index.ts | 34 ++++++--- 8 files changed, 171 insertions(+), 69 deletions(-) diff --git a/src/core/features/course/pages/contents/contents.ts b/src/core/features/course/pages/contents/contents.ts index 7492207ed..2301f3463 100644 --- a/src/core/features/course/pages/contents/contents.ts +++ b/src/core/features/course/pages/contents/contents.ts @@ -18,7 +18,7 @@ import { IonContent, IonRefresher } from '@ionic/angular'; import { CoreSites } from '@services/sites'; import { CoreDomUtils } from '@services/utils/dom'; import { CoreUtils } from '@services/utils/utils'; -import { CoreCourses, CoreCourseAnyCourseData } from '@features/courses/services/courses'; +import { CoreCourses, CoreCourseAnyCourseData, CoreCoursesProvider } from '@features/courses/services/courses'; import { CoreCourse, CoreCourseCompletionActivityStatus, @@ -78,14 +78,34 @@ export class CoreCourseContentsPage implements OnInit, OnDestroy { protected formatOptions?: Record; protected completionObserver?: CoreEventObserver; protected courseStatusObserver?: CoreEventObserver; + protected siteUpdatedObserver?: CoreEventObserver; + protected downloadEnabledObserver?: CoreEventObserver; protected syncObserver?: CoreEventObserver; protected isDestroyed = false; protected modulesHaveCompletion = false; protected isGuest?: boolean; protected debouncedUpdateCachedCompletion?: () => void; // Update the cached completion after a certain time. + constructor() { + // Refresh the enabled flags if site is updated. + this.siteUpdatedObserver = CoreEvents.on(CoreEvents.SITE_UPDATED, () => { + this.downloadCourseEnabled = !CoreCourses.isDownloadCourseDisabledInSite(); + + this.displayEnableDownload = !CoreSites.getRequiredCurrentSite().isOfflineDisabled() && + CoreCourseFormatDelegate.displayEnableDownload(this.course); + + this.downloadEnabled = this.displayEnableDownload && this.downloadEnabled; + + this.initListeners(); + }, CoreSites.getCurrentSiteId()); + + this.downloadEnabledObserver = CoreEvents.on(CoreCoursesProvider.EVENT_DASHBOARD_DOWNLOAD_ENABLED_CHANGED, (data) => { + this.toggleDownload(data.enabled); + }); + } + /** - * Component being initialized. + * @inheritdoc */ async ngOnInit(): Promise { @@ -103,10 +123,12 @@ export class CoreCourseContentsPage implements OnInit, OnDestroy { this.moduleId = CoreNavigator.getRouteNumberParam('moduleId'); this.isGuest = CoreNavigator.getRouteBooleanParam('isGuest'); - this.displayEnableDownload = !CoreSites.getCurrentSite()?.isOfflineDisabled() && + this.displayEnableDownload = !CoreSites.getRequiredCurrentSite().isOfflineDisabled() && CoreCourseFormatDelegate.displayEnableDownload(this.course); this.downloadCourseEnabled = !CoreCourses.isDownloadCourseDisabledInSite(); + this.downloadEnabled = this.displayEnableDownload && CoreCourses.getCourseDownloadOptionsEnabled(); + this.debouncedUpdateCachedCompletion = CoreUtils.debounce(() => { if (this.modulesHaveCompletion) { CoreUtils.ignoreErrors(CoreCourse.getSections(this.course.id, false, true)); @@ -137,7 +159,7 @@ export class CoreCourseContentsPage implements OnInit, OnDestroy { * @return Promise resolved when done. */ protected async initListeners(): Promise { - if (this.downloadCourseEnabled) { + if (this.downloadCourseEnabled && !this.courseStatusObserver) { // Listen for changes in course status. this.courseStatusObserver = CoreEvents.on(CoreEvents.COURSE_STATUS_CHANGED, (data) => { if (data.courseId == this.course.id || data.courseId == CoreCourseProvider.ALL_COURSES_CLEARED) { @@ -152,26 +174,30 @@ export class CoreCourseContentsPage implements OnInit, OnDestroy { return; } - this.completionObserver = CoreEvents.on( - CoreEvents.COMPLETION_MODULE_VIEWED, - (data) => { - if (data && data.courseId == this.course.id) { - this.refreshAfterCompletionChange(true); + if (!this.completionObserver) { + this.completionObserver = CoreEvents.on( + CoreEvents.COMPLETION_MODULE_VIEWED, + (data) => { + if (data && data.courseId == this.course.id) { + this.refreshAfterCompletionChange(true); + } + }, + ); + } + + if (!this.syncObserver) { + this.syncObserver = CoreEvents.on(CoreCourseSyncProvider.AUTO_SYNCED, (data) => { + if (!data || data.courseId != this.course.id) { + return; } - }, - ); - this.syncObserver = CoreEvents.on(CoreCourseSyncProvider.AUTO_SYNCED, (data) => { - if (!data || data.courseId != this.course.id) { - return; - } + this.refreshAfterCompletionChange(false); - this.refreshAfterCompletionChange(false); - - if (data.warnings && data.warnings[0]) { - CoreDomUtils.showErrorModal(data.warnings[0]); - } - }); + if (data.warnings && data.warnings[0]) { + CoreDomUtils.showErrorModal(data.warnings[0]); + } + }); + } } /** @@ -472,7 +498,8 @@ export class CoreCourseContentsPage implements OnInit, OnDestroy { * @param enable Whether enable or disable download enabled toggle. */ toggleDownload(enable: boolean): void { - this.downloadEnabled = enable; + this.downloadEnabled = + CoreCourses.setCourseDownloadOptionsEnabled(this.displayEnableDownload && enable); } /** @@ -517,6 +544,8 @@ export class CoreCourseContentsPage implements OnInit, OnDestroy { this.completionObserver?.off(); this.courseStatusObserver?.off(); this.syncObserver?.off(); + this.siteUpdatedObserver?.off(); + this.downloadEnabledObserver?.off(); } /** diff --git a/src/core/features/courses/pages/categories/categories.ts b/src/core/features/courses/pages/categories/categories.ts index d3de228a0..c5969bcae 100644 --- a/src/core/features/courses/pages/categories/categories.ts +++ b/src/core/features/courses/pages/categories/categories.ts @@ -49,6 +49,7 @@ export class CoreCoursesCategoriesPage implements OnInit, OnDestroy { protected categoryId = 0; protected myCoursesObserver: CoreEventObserver; protected siteUpdatedObserver: CoreEventObserver; + protected downloadEnabledObserver: CoreEventObserver; protected isDestroyed = false; constructor() { @@ -75,6 +76,10 @@ export class CoreCoursesCategoriesPage implements OnInit, OnDestroy { this.downloadEnabled = (this.downloadCourseEnabled || this.downloadCoursesEnabled) && this.downloadEnabled; }, this.currentSiteId); + + this.downloadEnabledObserver = CoreEvents.on(CoreCoursesProvider.EVENT_DASHBOARD_DOWNLOAD_ENABLED_CHANGED, (data) => { + this.toggleDownload(data.enabled); + }); } /** @@ -88,6 +93,9 @@ export class CoreCoursesCategoriesPage implements OnInit, OnDestroy { this.downloadCoursesEnabled = !CoreCourses.isDownloadCoursesDisabledInSite(); this.myCoursesEnabled = !CoreCourses.isMyCoursesDisabledInSite(); + this.downloadEnabled = + (this.downloadCourseEnabled || this.downloadCoursesEnabled) && CoreCourses.getCourseDownloadOptionsEnabled(); + this.fetchCategories().finally(() => { this.categoriesLoaded = true; }); @@ -202,17 +210,21 @@ export class CoreCoursesCategoriesPage implements OnInit, OnDestroy { /** * Toggle download enabled. + * + * @param enable If enable or disable. */ - toggleDownload(enabled: boolean): void { - this.downloadEnabled = enabled; + toggleDownload(enable: boolean): void { + this.downloadEnabled = + CoreCourses.setCourseDownloadOptionsEnabled((this.downloadCourseEnabled || this.downloadCoursesEnabled) && enable); } /** * @inheritdoc */ ngOnDestroy(): void { - this.myCoursesObserver?.off(); - this.siteUpdatedObserver?.off(); + this.myCoursesObserver.off(); + this.siteUpdatedObserver.off(); + this.downloadEnabledObserver.off(); this.isDestroyed = true; } diff --git a/src/core/features/courses/pages/dashboard/dashboard.html b/src/core/features/courses/pages/dashboard/dashboard.html index a7f25bbee..a7dc2fc79 100644 --- a/src/core/features/courses/pages/dashboard/dashboard.html +++ b/src/core/features/courses/pages/dashboard/dashboard.html @@ -4,11 +4,11 @@ + [content]="'core.settings.showdownloadoptions' | translate" (action)="switchDownload(!downloadEnabled)" + iconAction="toggle" [toggle]="downloadEnabled"> + [content]="'addon.storagemanager.managestorage' | translate" + (action)="manageCoursesStorage()" iconAction="fas-archive"> diff --git a/src/core/features/courses/pages/dashboard/dashboard.ts b/src/core/features/courses/pages/dashboard/dashboard.ts index f895f177b..28180ea4e 100644 --- a/src/core/features/courses/pages/dashboard/dashboard.ts +++ b/src/core/features/courses/pages/dashboard/dashboard.ts @@ -44,25 +44,35 @@ export class CoreCoursesDashboardPage implements OnInit, OnDestroy { blocks: Partial[] = []; loaded = false; - protected updateSiteObserver?: CoreEventObserver; - - /** - * Initialize the component. - */ - ngOnInit(): void { - this.searchEnabled = !CoreCourses.isSearchCoursesDisabledInSite(); - this.downloadCourseEnabled = !CoreCourses.isDownloadCourseDisabledInSite(); - this.downloadCoursesEnabled = !CoreCourses.isDownloadCoursesDisabledInSite(); + protected updateSiteObserver: CoreEventObserver; + protected downloadEnabledObserver: CoreEventObserver; + constructor() { // Refresh the enabled flags if site is updated. this.updateSiteObserver = CoreEvents.on(CoreEvents.SITE_UPDATED, () => { this.searchEnabled = !CoreCourses.isSearchCoursesDisabledInSite(); this.downloadCourseEnabled = !CoreCourses.isDownloadCourseDisabledInSite(); this.downloadCoursesEnabled = !CoreCourses.isDownloadCoursesDisabledInSite(); - this.switchDownload(this.downloadEnabled && this.downloadCourseEnabled && this.downloadCoursesEnabled); + this.switchDownload(this.downloadEnabled); }, CoreSites.getCurrentSiteId()); + this.downloadEnabledObserver = CoreEvents.on(CoreCoursesProvider.EVENT_DASHBOARD_DOWNLOAD_ENABLED_CHANGED, (data) => { + this.switchDownload(data.enabled); + }); + } + + /** + * @inheritdoc + */ + ngOnInit(): void { + this.searchEnabled = !CoreCourses.isSearchCoursesDisabledInSite(); + this.downloadCourseEnabled = !CoreCourses.isDownloadCourseDisabledInSite(); + this.downloadCoursesEnabled = !CoreCourses.isDownloadCoursesDisabledInSite(); + + this.downloadEnabled = + (this.downloadCourseEnabled || this.downloadCoursesEnabled) && CoreCourses.getCourseDownloadOptionsEnabled(); + this.loadContent(); } @@ -143,8 +153,8 @@ export class CoreCoursesDashboardPage implements OnInit, OnDestroy { * @param enable If enable or disable. */ protected switchDownload(enable: boolean): void { - this.downloadEnabled = (this.downloadCourseEnabled || this.downloadCoursesEnabled) && enable; - CoreEvents.trigger(CoreCoursesProvider.EVENT_DASHBOARD_DOWNLOAD_ENABLED_CHANGED, { enabled: this.downloadEnabled }); + this.downloadEnabled = + CoreCourses.setCourseDownloadOptionsEnabled((this.downloadCourseEnabled || this.downloadCoursesEnabled) && enable); } /** @@ -165,7 +175,8 @@ export class CoreCoursesDashboardPage implements OnInit, OnDestroy { * Component being destroyed. */ ngOnDestroy(): void { - this.updateSiteObserver?.off(); + this.updateSiteObserver.off(); + this.downloadEnabledObserver.off(); } } diff --git a/src/core/features/courses/pages/list/list.ts b/src/core/features/courses/pages/list/list.ts index 7d0174397..a510d5b5b 100644 --- a/src/core/features/courses/pages/list/list.ts +++ b/src/core/features/courses/pages/list/list.ts @@ -58,6 +58,7 @@ export class CoreCoursesListPage implements OnInit, OnDestroy { protected searchText = ''; protected myCoursesObserver: CoreEventObserver; protected siteUpdatedObserver: CoreEventObserver; + protected downloadEnabledObserver: CoreEventObserver; protected courseIds = ''; protected isDestroyed = false; @@ -92,6 +93,10 @@ export class CoreCoursesListPage implements OnInit, OnDestroy { this.fetchCourses(); } }, this.currentSiteId); + + this.downloadEnabledObserver = CoreEvents.on(CoreCoursesProvider.EVENT_DASHBOARD_DOWNLOAD_ENABLED_CHANGED, (data) => { + this.toggleDownload(data.enabled); + }); } /** @@ -101,6 +106,9 @@ export class CoreCoursesListPage implements OnInit, OnDestroy { this.downloadCourseEnabled = !CoreCourses.isDownloadCourseDisabledInSite(); this.downloadCoursesEnabled = !CoreCourses.isDownloadCoursesDisabledInSite(); + this.downloadEnabled = + (this.downloadCourseEnabled || this.downloadCoursesEnabled) && CoreCourses.getCourseDownloadOptionsEnabled(); + this.mode = CoreNavigator.getRouteParam('mode') || this.mode; this.myCoursesEnabled = !CoreCourses.isMyCoursesDisabledInSite(); @@ -269,27 +277,33 @@ export class CoreCoursesListPage implements OnInit, OnDestroy { /** * Toggle show only my courses. + * + * @param enable If enable or disable. */ - toggleEnrolled(enabled: boolean): void { + toggleEnrolled(enable: boolean): void { this.coursesLoaded = false; - this.showOnlyEnrolled = enabled; + this.showOnlyEnrolled = enable; this.fetchCourses(); } /** * Toggle download enabled. + * + * @param enable If enable or disable. */ - toggleDownload(enabled: boolean): void { - this.downloadEnabled = enabled; + toggleDownload(enable: boolean): void { + this.downloadEnabled = + CoreCourses.setCourseDownloadOptionsEnabled((this.downloadCourseEnabled || this.downloadCoursesEnabled) && enable); } /** * @inheritdoc */ ngOnDestroy(): void { - this.myCoursesObserver?.off(); - this.siteUpdatedObserver?.off(); + this.myCoursesObserver.off(); + this.siteUpdatedObserver.off(); + this.downloadEnabledObserver.off(); this.isDestroyed = true; } diff --git a/src/core/features/courses/services/courses.ts b/src/core/features/courses/services/courses.ts index 7b52afce7..9ccd82fbc 100644 --- a/src/core/features/courses/services/courses.ts +++ b/src/core/features/courses/services/courses.ts @@ -13,7 +13,6 @@ // limitations under the License. import { Injectable } from '@angular/core'; -import { CoreLogger } from '@singletons/logger'; import { CoreSites, CoreSitesCommonWSOptions, CoreSitesReadingStrategy } from '@services/sites'; import { CoreSite, CoreSiteWSPreSets } from '@classes/site'; import { makeSingleton } from '@singletons'; @@ -63,12 +62,9 @@ export class CoreCoursesProvider { static readonly STATE_HIDDEN = 'hidden'; static readonly STATE_FAVOURITE = 'favourite'; - protected logger: CoreLogger; protected userCoursesIds: { [id: number]: boolean } = {}; // Use an object to make it faster to search. - constructor() { - this.logger = CoreLogger.getInstance('CoreCoursesProvider'); - } + protected downloadOptionsEnabled = false; /** * Whether current site supports getting course options. @@ -1220,6 +1216,32 @@ export class CoreCoursesProvider { return site.write('core_course_set_favourite_courses', params); } + /** + * Get download options enabled option. + * + * @return True if enabled, false otherwise. + */ + getCourseDownloadOptionsEnabled(): boolean { + return this.downloadOptionsEnabled; + } + + /** + * Set trigger and save the download option. + * + * @param enable True to enable, false to disable. + * @return Current status. + */ + setCourseDownloadOptionsEnabled(enable: boolean): boolean { + if (this.downloadOptionsEnabled == enable) { + return enable; + } + + this.downloadOptionsEnabled = enable; + CoreEvents.trigger(CoreCoursesProvider.EVENT_DASHBOARD_DOWNLOAD_ENABLED_CHANGED, { enabled: enable }); + + return enable; + } + } export const CoreCourses = makeSingleton(CoreCoursesProvider); diff --git a/src/core/features/sitehome/pages/index/index.html b/src/core/features/sitehome/pages/index/index.html index 64ff7d280..179a73f10 100644 --- a/src/core/features/sitehome/pages/index/index.html +++ b/src/core/features/sitehome/pages/index/index.html @@ -3,12 +3,12 @@ - + + [content]="'addon.storagemanager.managestorage' | translate" + (action)="manageCoursesStorage()" iconAction="fas-archive"> diff --git a/src/core/features/sitehome/pages/index/index.ts b/src/core/features/sitehome/pages/index/index.ts index b33f2e605..4f2aff5c5 100644 --- a/src/core/features/sitehome/pages/index/index.ts +++ b/src/core/features/sitehome/pages/index/index.ts @@ -50,22 +50,32 @@ export class CoreSiteHomeIndexPage implements OnInit, OnDestroy { siteHomeId = 1; currentSite!: CoreSite; searchEnabled = false; + displayEnableDownload = false; downloadEnabled = false; newsForumModule?: NewsForum; - protected updateSiteObserver?: CoreEventObserver; - - /** - * Page being initialized. - */ - ngOnInit(): void { - this.searchEnabled = !CoreCourses.isSearchCoursesDisabledInSite(); + protected updateSiteObserver: CoreEventObserver; + protected downloadEnabledObserver: CoreEventObserver; + constructor() { // Refresh the enabled flags if site is updated. this.updateSiteObserver = CoreEvents.on(CoreEvents.SITE_UPDATED, () => { this.searchEnabled = !CoreCourses.isSearchCoursesDisabledInSite(); + + this.displayEnableDownload = !CoreSites.getRequiredCurrentSite().isOfflineDisabled(); }, CoreSites.getCurrentSiteId()); + this.downloadEnabledObserver = CoreEvents.on(CoreCoursesProvider.EVENT_DASHBOARD_DOWNLOAD_ENABLED_CHANGED, (data) => { + this.switchDownload(data.enabled); + }); + } + + /** + * @inheritdoc + */ + ngOnInit(): void { + this.searchEnabled = !CoreCourses.isSearchCoursesDisabledInSite(); + this.currentSite = CoreSites.getRequiredCurrentSite(); this.siteHomeId = CoreSites.getCurrentSiteHomeId(); @@ -75,6 +85,9 @@ export class CoreSiteHomeIndexPage implements OnInit, OnDestroy { CoreCourseHelper.openModule(module, this.siteHomeId, undefined, modParams); } + this.displayEnableDownload = !CoreSites.getRequiredCurrentSite().isOfflineDisabled(); + this.downloadEnabled = CoreCourses.getCourseDownloadOptionsEnabled(); + this.loadContent().finally(() => { this.dataLoaded = true; }); @@ -186,8 +199,8 @@ export class CoreSiteHomeIndexPage implements OnInit, OnDestroy { * @param enable If enable or disable. */ protected switchDownload(enable: boolean): void { - this.downloadEnabled = enable; - CoreEvents.trigger(CoreCoursesProvider.EVENT_DASHBOARD_DOWNLOAD_ENABLED_CHANGED, { enabled: this.downloadEnabled }); + this.downloadEnabled = + CoreCourses.setCourseDownloadOptionsEnabled(enable); } /** @@ -229,7 +242,8 @@ export class CoreSiteHomeIndexPage implements OnInit, OnDestroy { * Component being destroyed. */ ngOnDestroy(): void { - this.updateSiteObserver?.off(); + this.updateSiteObserver.off(); + this.downloadEnabledObserver.off(); } }