forked from EVOgeek/Vmeda.Online
		
	
						commit
						07f661e5ab
					
				| @ -29,7 +29,7 @@ | ||||
|             <ion-item class="ion-text-wrap" *ngIf="activityInstructions"> | ||||
|                 <ion-label> | ||||
|                     <core-format-text [text]="activityInstructions" [component]="component" [componentId]="moduleId" contextLevel="module" | ||||
|                         [contextInstanceId]="moduleId" [courseId]="courseId" [maxHeight]="120"> | ||||
|                         [contextInstanceId]="moduleId" [courseId]="courseId"> | ||||
|                     </core-format-text> | ||||
|                 </ion-label> | ||||
|             </ion-item> | ||||
|  | ||||
| @ -19,10 +19,6 @@ import { CoreSiteError, CoreSiteErrorOptions } from '@classes/errors/siteerror'; | ||||
|  */ | ||||
| export class CoreAjaxError extends CoreSiteError { | ||||
| 
 | ||||
|     /** | ||||
|      * @deprecated since 4.0. AJAX endpoint should always be available in supported Moodle versions. | ||||
|      */ | ||||
|     available = 1; | ||||
|     status?: number; | ||||
| 
 | ||||
|     constructor(messageOrOptions: string | CoreSiteErrorOptions, available?: number, status?: number) { | ||||
|  | ||||
| @ -1634,38 +1634,6 @@ export class CoreSite { | ||||
|         return CoreUrlUtils.addParamsToUrl(CorePath.concatenatePaths(this.siteUrl, path), params, anchor); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Check if the local_mobile plugin is installed in the Moodle site. | ||||
|      * | ||||
|      * @returns Promise resolved when the check is done. | ||||
|      * @deprecated since 4.0. | ||||
|      */ | ||||
|     // eslint-disable-next-line deprecation/deprecation
 | ||||
|     async checkLocalMobilePlugin(): Promise<LocalMobileResponse> { | ||||
|         // Not used anymore.
 | ||||
|         return { code: 0, coreSupported: true }; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Check if local_mobile has been installed in Moodle. | ||||
|      * | ||||
|      * @returns Whether the App is able to use local_mobile plugin for this site. | ||||
|      * @deprecated since 4.0. | ||||
|      */ | ||||
|     checkIfAppUsesLocalMobile(): boolean { | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Check if local_mobile has been installed in Moodle but the app is not using it. | ||||
|      * | ||||
|      * @returns Promise resolved it local_mobile was added, rejected otherwise. | ||||
|      * @deprecated since 4.0. | ||||
|      */ | ||||
|     async checkIfLocalMobileInstalledAndNotUsed(): Promise<void> { | ||||
|         throw new CoreError('Deprecated.'); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Check if a URL belongs to this site. | ||||
|      * | ||||
| @ -2666,33 +2634,6 @@ export type CoreSiteWSPreSets = { | ||||
|     updateInBackground?: boolean; | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
|  * Response of checking local_mobile status. | ||||
|  * | ||||
|  * @deprecated since 4.0. | ||||
|  */ | ||||
| export type LocalMobileResponse = { | ||||
|     /** | ||||
|      * Code to identify the authentication method to use. | ||||
|      */ | ||||
|     code: number; | ||||
| 
 | ||||
|     /** | ||||
|      * Name of the service to use. | ||||
|      */ | ||||
|     service?: string; | ||||
| 
 | ||||
|     /** | ||||
|      * Code of the warning message. | ||||
|      */ | ||||
|     warning?: string; | ||||
| 
 | ||||
|     /** | ||||
|      * Whether core SSO is supported. | ||||
|      */ | ||||
|     coreSupported?: boolean; | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
|  * Info of a request waiting in the queue. | ||||
|  */ | ||||
|  | ||||
| @ -13,7 +13,6 @@ | ||||
| // limitations under the License.
 | ||||
| 
 | ||||
| import { Component, Input, Output, OnInit, OnDestroy, EventEmitter, OnChanges, SimpleChange } from '@angular/core'; | ||||
| import { CoreLogger } from '@singletons/logger'; | ||||
| import { CoreContextMenuComponent } from '../context-menu/context-menu'; | ||||
| 
 | ||||
| /** | ||||
| @ -58,11 +57,6 @@ export class CoreContextMenuItemComponent implements OnInit, OnDestroy, OnChange | ||||
|     @Output() onClosed?: EventEmitter<() => void>; // Will emit an event when the popover is closed because the item was clicked.
 | ||||
|     @Output() toggleChange = new EventEmitter<boolean>();// Will emit an event when toggle changes to enable 2-way data binding.
 | ||||
| 
 | ||||
|     /** | ||||
|      * @deprecated since 4.0. Not used anymore. | ||||
|      */ | ||||
|     @Input() iconDescription?: string; | ||||
| 
 | ||||
|     protected hasAction = false; | ||||
|     protected destroyed = false; | ||||
| 
 | ||||
| @ -92,12 +86,6 @@ export class CoreContextMenuItemComponent implements OnInit, OnDestroy, OnChange | ||||
|         if (!this.destroyed) { | ||||
|             this.ctxtMenu.addItem(this); | ||||
|         } | ||||
| 
 | ||||
|         // eslint-disable-next-line deprecation/deprecation
 | ||||
|         if (this.iconDescription !== undefined) { | ||||
|             CoreLogger.getInstance('CoreContextMenuItemComponent') | ||||
|                 .warn('iconDescription Input is deprecated and should not be used'); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | ||||
| @ -35,10 +35,6 @@ export class CoreDownloadRefreshComponent { | ||||
|     @Input() statusTranslatable?: string; // Download status translatable string.
 | ||||
|     @Input() enabled = false; // Whether the download is enabled.
 | ||||
|     @Input() loading = true; // Force loading status when is not downloading.
 | ||||
|     /** | ||||
|      * @deprecated since 4.0. Not used anymore. | ||||
|      */ | ||||
|     @Input() size = ''; // Size of the buttons.
 | ||||
|     @Input() canTrustDownload = false; // If false, refresh will be shown if downloaded.
 | ||||
|     @Output() action: EventEmitter<boolean>; // Will emit an event when the item clicked.
 | ||||
| 
 | ||||
|  | ||||
| @ -35,11 +35,6 @@ export class CoreEmptyBoxComponent { | ||||
|     @Input() image?: string; // Image source. If an icon is provided, image won't be used.
 | ||||
|     @Input() flipIconRtl = false; // Whether to flip the icon in RTL. Defaults to false.
 | ||||
| 
 | ||||
|     /** | ||||
|      * @deprecated since 4.0. Not used anymore. | ||||
|      */ | ||||
|     @Input() inline = false; | ||||
| 
 | ||||
|     @HostBinding('class.dimmed') | ||||
|     get isDimmed(): boolean { | ||||
|         return this.dimmed; | ||||
|  | ||||
| @ -14,7 +14,6 @@ | ||||
| 
 | ||||
| import { Component, Input, OnInit, OnChanges, SimpleChange, ElementRef, AfterViewInit, OnDestroy } from '@angular/core'; | ||||
| 
 | ||||
| import { CoreEventLoadingChangedData, CoreEvents } from '@singletons/events'; | ||||
| import { CoreUtils } from '@services/utils/utils'; | ||||
| import { CoreAnimations } from '@components/animations'; | ||||
| import { Translate } from '@singletons'; | ||||
| @ -153,13 +152,6 @@ export class CoreLoadingComponent implements OnInit, OnChanges, AfterViewInit, A | ||||
|             this.lastScrollPosition = this.getScrollPosition(); | ||||
|             this.mutationObserver.disconnect(); | ||||
|         } | ||||
| 
 | ||||
|         // Event has been deprecated since app 4.0.
 | ||||
|         // eslint-disable-next-line deprecation/deprecation
 | ||||
|         CoreEvents.trigger(CoreEvents.CORE_LOADING_CHANGED, <CoreEventLoadingChangedData> { | ||||
|             loaded, | ||||
|             uniqueId: this.uniqueId, | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | ||||
| @ -78,10 +78,6 @@ export class CoreConstants { | ||||
|     // WS constants.
 | ||||
|     static readonly WS_TIMEOUT = 30000; // Timeout when not in WiFi.
 | ||||
|     static readonly WS_TIMEOUT_WIFI = 30000; // Timeout when in WiFi.
 | ||||
|     /** | ||||
|      * @deprecated since 4.0. Not used anymore. | ||||
|      */ | ||||
|     static readonly WS_PREFIX = 'local_mobile_'; | ||||
| 
 | ||||
|     // Login constants.
 | ||||
|     /** | ||||
|  | ||||
| @ -90,21 +90,6 @@ export class CoreFormatTextDirective implements OnChanges, OnDestroy, AsyncDirec | ||||
|     @Input() hideIfEmpty = false; // If true, the tag will contain nothing if text is empty.
 | ||||
|     @Input() disabled?: boolean; // If disabled, autoplay elements will be disabled.
 | ||||
| 
 | ||||
|     /** | ||||
|      * @deprecated since 4.0. Not used anymore. | ||||
|      */ | ||||
|     @Input() fullOnClick?: boolean | string; | ||||
|     /** | ||||
|      * @deprecated since 4.0. Not used anymore. | ||||
|      */ | ||||
|     @Input() fullTitle?: string; | ||||
|     /** | ||||
|      * Max height in pixels to render the content box. It should be 50 at least to make sense. | ||||
|      * | ||||
|      * @deprecated since 4.0 Use collapsible-item directive instead. | ||||
|      */ | ||||
|     @Input() maxHeight?: number; | ||||
| 
 | ||||
|     @Output() afterRender: EventEmitter<void>; // Called when the data is rendered.
 | ||||
|     @Output() onClick: EventEmitter<void> = new EventEmitter(); // Called when clicked.
 | ||||
| 
 | ||||
| @ -380,15 +365,6 @@ export class CoreFormatTextDirective implements OnChanges, OnDestroy, AsyncDirec | ||||
| 
 | ||||
|         await CoreUtils.nextTick(); | ||||
| 
 | ||||
|         // Use collapsible-item directive instead.
 | ||||
|         // eslint-disable-next-line deprecation/deprecation
 | ||||
|         if (this.maxHeight && !this.collapsible) { | ||||
|             this.collapsible = new CoreCollapsibleItemDirective(new ElementRef(this.element)); | ||||
|             // eslint-disable-next-line deprecation/deprecation
 | ||||
|             this.collapsible.height = this.maxHeight; | ||||
|             this.collapsible.ngOnInit(); | ||||
|         } | ||||
| 
 | ||||
|         // Add magnifying glasses to images.
 | ||||
|         this.addMagnifyingGlasses(); | ||||
| 
 | ||||
|  | ||||
| @ -13,7 +13,6 @@ | ||||
| // limitations under the License.
 | ||||
| 
 | ||||
| import { CoreContentLinksHandlerBase } from './base-handler'; | ||||
| import { Params } from '@angular/router'; | ||||
| import { CoreContentLinksAction } from '../services/contentlinks-delegate'; | ||||
| import { CoreCourseHelper } from '@features/course/services/course-helper'; | ||||
| import { CoreNavigationOptions } from '@services/navigator'; | ||||
| @ -52,20 +51,6 @@ export class CoreContentLinksModuleIndexHandler extends CoreContentLinksHandlerB | ||||
|         this.featureName = 'CoreCourseModuleDelegate_' + addon; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Get the mod params necessary to open an activity. | ||||
|      * | ||||
|      * @param url The URL to treat. | ||||
|      * @param params The params of the URL. E.g. 'mysite.com?id=1' -> {id: 1} | ||||
|      * @param courseId Course ID related to the URL. Optional but recommended. | ||||
|      * @returns List of params to pass to navigateToModule / navigateToModuleByInstance. | ||||
|      * @deprecated since 4.0. Not used anymore. | ||||
|      */ | ||||
|     // eslint-disable-next-line @typescript-eslint/no-unused-vars
 | ||||
|     getPageParams(url: string, params: Record<string, string>, courseId?: number): Params { | ||||
|         return {}; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Get the navigation options to open the module. | ||||
|      * | ||||
| @ -97,19 +82,6 @@ export class CoreContentLinksModuleIndexHandler extends CoreContentLinksHandlerB | ||||
|     ): CoreContentLinksAction[] | Promise<CoreContentLinksAction[]> { | ||||
| 
 | ||||
|         courseId = Number(courseId || params.courseid || params.cid); | ||||
|         const getModNavOptions = (siteId: string): CoreNavigationOptions => { | ||||
|             let modNavOptions = this.getModNavOptions(url, params, siteId, courseId); | ||||
|             if (!modNavOptions) { | ||||
|                 // Use the old function, currently deprecated.
 | ||||
|                 // eslint-disable-next-line deprecation/deprecation
 | ||||
|                 const pageParams = this.getPageParams(url, params, courseId); | ||||
|                 if (pageParams && Object.keys(pageParams).length > 0) { | ||||
|                     modNavOptions = { params: pageParams }; | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             return modNavOptions; | ||||
|         }; | ||||
| 
 | ||||
|         if (this.instanceIdParam && params[this.instanceIdParam] !== undefined) { | ||||
|             const instanceId = parseInt(params[this.instanceIdParam], 10); | ||||
| @ -122,7 +94,7 @@ export class CoreContentLinksModuleIndexHandler extends CoreContentLinksHandlerB | ||||
|                         { | ||||
|                             courseId, | ||||
|                             useModNameToGetModule: this.useModNameToGetModule, | ||||
|                             modNavOptions: getModNavOptions(siteId), | ||||
|                             modNavOptions: this.getModNavOptions(url, params, siteId, courseId), | ||||
|                             siteId, | ||||
|                         }, | ||||
|                     ); | ||||
| @ -137,7 +109,7 @@ export class CoreContentLinksModuleIndexHandler extends CoreContentLinksHandlerB | ||||
|                     { | ||||
|                         courseId, | ||||
|                         modName: this.useModNameToGetModule ? this.modName : undefined, | ||||
|                         modNavOptions: getModNavOptions(siteId), | ||||
|                         modNavOptions: this.getModNavOptions(url, params, siteId, courseId), | ||||
|                         siteId, | ||||
|                     }, | ||||
|                 ); | ||||
|  | ||||
| @ -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; | ||||
|     }; | ||||
| 
 | ||||
| } | ||||
|  | ||||
| @ -148,14 +148,6 @@ export class CoreCourseIndexPage implements OnInit, OnDestroy { | ||||
| 
 | ||||
|         this.modNavOptions = CoreNavigator.getRouteParam<CoreNavigationOptions>('modNavOptions'); | ||||
|         this.openModule = CoreNavigator.getRouteBooleanParam('openModule') ?? true; // If false, just scroll to module.
 | ||||
|         if (!this.modNavOptions) { | ||||
|             // Fallback to old way of passing params. @deprecated since 4.0.
 | ||||
|             const modParams = CoreNavigator.getRouteParam<Params>('modParams'); | ||||
|             if (modParams) { | ||||
|                 this.modNavOptions = { params: modParams }; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         this.currentPagePath = CoreNavigator.getCurrentPath(); | ||||
|         this.contentsTab.page = CorePath.concatenatePaths(this.currentPagePath, this.contentsTab.page); | ||||
|         this.contentsTab.pageParams = { | ||||
|  | ||||
| @ -42,7 +42,6 @@ import { | ||||
|     CoreEnrolledCourseData, | ||||
| } from '@features/courses/services/courses'; | ||||
| import { CoreArray } from '@singletons/array'; | ||||
| import { CoreIonLoadingElement } from '@classes/ion-loading'; | ||||
| import { CoreCourseOffline } from './course-offline'; | ||||
| import { | ||||
|     CoreCourseOptionsDelegate, | ||||
| @ -258,22 +257,6 @@ export class CoreCourseHelperProvider { | ||||
|         return section.uservisible !== false; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Calculate completion data of a module. | ||||
|      * | ||||
|      * @param module Module. | ||||
|      * @deprecated since 4.0. | ||||
|      */ | ||||
|     calculateModuleCompletionData(module: CoreCourseModuleData): void { | ||||
|         if (!module.completiondata || !module.completion) { | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         module.completiondata.courseId = module.course; | ||||
|         module.completiondata.tracking = module.completion; | ||||
|         module.completiondata.cmid = module.id; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Calculate the status of a section. | ||||
|      * | ||||
| @ -312,8 +295,6 @@ export class CoreCourseHelperProvider { | ||||
|         } | ||||
| 
 | ||||
|         sectionWithStatus.downloadStatus = result.status; | ||||
|         // eslint-disable-next-line deprecation/deprecation
 | ||||
|         sectionWithStatus.canCheckUpdates = true; | ||||
| 
 | ||||
|         // Set this section data.
 | ||||
|         if (result.status !== CoreConstants.DOWNLOADING) { | ||||
| @ -375,8 +356,6 @@ export class CoreCourseHelperProvider { | ||||
|             if (allSectionsSection) { | ||||
|                 // Set "All sections" data.
 | ||||
|                 allSectionsSection.downloadStatus = allSectionsStatus; | ||||
|                 // eslint-disable-next-line deprecation/deprecation
 | ||||
|                 allSectionsSection.canCheckUpdates = true; | ||||
|                 allSectionsSection.isDownloading = allSectionsStatus === CoreConstants.DOWNLOADING; | ||||
|             } | ||||
| 
 | ||||
| @ -514,32 +493,6 @@ export class CoreCourseHelperProvider { | ||||
|         return CoreUtils.allPromises(promises); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Show confirmation dialog and then remove a module files. | ||||
|      * | ||||
|      * @param module Module to remove the files. | ||||
|      * @param courseId Course ID the module belongs to. | ||||
|      * @returns Promise resolved when done. | ||||
|      * @deprecated since 4.0. | ||||
|      */ | ||||
|     async confirmAndRemoveFiles(module: CoreCourseModuleData, courseId: number): Promise<void> { | ||||
|         let modal: CoreIonLoadingElement | undefined; | ||||
| 
 | ||||
|         try { | ||||
|             await CoreDomUtils.showDeleteConfirm('addon.storagemanager.confirmdeletedatafrom', { name: module.name }); | ||||
| 
 | ||||
|             modal = await CoreDomUtils.showModalLoading(); | ||||
| 
 | ||||
|             await this.removeModuleStoredData(module, courseId); | ||||
|         } catch (error) { | ||||
|             if (error) { | ||||
|                 CoreDomUtils.showErrorModal(error); | ||||
|             } | ||||
|         } finally { | ||||
|             modal?.dismiss(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Calculate the size to download a section and show a confirm modal if needed. | ||||
|      * | ||||
| @ -1358,31 +1311,6 @@ export class CoreCourseHelperProvider { | ||||
|         return CoreConstants.ICON_DOWNLOADING; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Get the course ID from a module instance ID, showing an error message if it can't be retrieved. | ||||
|      * | ||||
|      * @param instanceId Instance ID. | ||||
|      * @param moduleName Name of the module. E.g. 'glossary'. | ||||
|      * @param siteId Site ID. If not defined, current site. | ||||
|      * @returns Promise resolved with the module's course ID. | ||||
|      * @deprecated since 4.0. | ||||
|      */ | ||||
|     async getModuleCourseIdByInstance(instanceId: number, moduleName: string, siteId?: string): Promise<number> { | ||||
|         try { | ||||
|             const cm = await CoreCourse.getModuleBasicInfoByInstance( | ||||
|                 instanceId, | ||||
|                 moduleName, | ||||
|                 { siteId, readingStrategy: CoreSitesReadingStrategy.PREFER_CACHE }, | ||||
|             ); | ||||
| 
 | ||||
|             return cm.course; | ||||
|         } catch (error) { | ||||
|             CoreDomUtils.showErrorModalDefault(error, 'core.course.errorgetmodule', true); | ||||
| 
 | ||||
|             throw error; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Get prefetch info for a module. | ||||
|      * | ||||
| @ -1805,8 +1733,6 @@ export class CoreCourseHelperProvider { | ||||
| 
 | ||||
|             // Set "All sections" data.
 | ||||
|             section.downloadStatus = allSectionsStatus; | ||||
|             // eslint-disable-next-line deprecation/deprecation
 | ||||
|             section.canCheckUpdates = true; | ||||
|             section.isDownloading = allSectionsStatus === CoreConstants.DOWNLOADING; | ||||
|         } finally { | ||||
|             section.isDownloading = false; | ||||
| @ -2120,10 +2046,6 @@ export type CoreCourseSection = CoreCourseWSSection & { | ||||
|  */ | ||||
| export type CoreCourseSectionWithStatus = CoreCourseSection & { | ||||
|     downloadStatus?: string; // Section status.
 | ||||
|     /** | ||||
|      * @deprecated since 4.0. | ||||
|      */ | ||||
|     canCheckUpdates?: boolean; // Whether can check updates.
 | ||||
|     isDownloading?: boolean; // Whether section is being downloaded.
 | ||||
|     total?: number; // Total of modules being downloaded.
 | ||||
|     count?: number; // Number of downloaded modules.
 | ||||
| @ -2141,13 +2063,6 @@ export type CoreCourseModuleData = Omit<CoreCourseGetContentsWSModule, 'completi | ||||
|     section: number; | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
|  * Module with calculated data. | ||||
|  * | ||||
|  * @deprecated since 4.0. Use CoreCourseModuleData instead. | ||||
|  */ | ||||
| export type CoreCourseModule = CoreCourseModuleData; | ||||
| 
 | ||||
| /** | ||||
|  * Module completion with calculated data. | ||||
|  */ | ||||
|  | ||||
| @ -110,36 +110,6 @@ export class CoreCourseProvider { | ||||
|     static readonly ACCESS_DEFAULT = 'courses_access_default'; | ||||
|     static readonly ALL_COURSES_CLEARED = -1; | ||||
| 
 | ||||
|     /** | ||||
|      * @deprecated since 4.0, use CoreCourseModuleCompletionTracking.COMPLETION_TRACKING_NONE instead. | ||||
|      */ | ||||
|     static readonly COMPLETION_TRACKING_NONE = 0; | ||||
|     /** | ||||
|      * @deprecated since 4.0, use CoreCourseModuleCompletionTracking.COMPLETION_TRACKING_MANUAL instead. | ||||
|      */ | ||||
|     static readonly COMPLETION_TRACKING_MANUAL = 1; | ||||
|     /** | ||||
|      * @deprecated since 4.0, use CoreCourseModuleCompletionTracking.COMPLETION_TRACKING_AUTOMATIC instead. | ||||
|      */ | ||||
|     static readonly COMPLETION_TRACKING_AUTOMATIC = 2; | ||||
| 
 | ||||
|     /** | ||||
|      * @deprecated since 4.0, use CoreCourseModuleCompletionStatus.COMPLETION_INCOMPLETE instead. | ||||
|      */ | ||||
|     static readonly COMPLETION_INCOMPLETE = 0; | ||||
|     /** | ||||
|      * @deprecated since 4.0, use CoreCourseModuleCompletionStatus.COMPLETION_COMPLETE instead. | ||||
|      */ | ||||
|     static readonly COMPLETION_COMPLETE = 1; | ||||
|     /** | ||||
|      * @deprecated since 4.0, use CoreCourseModuleCompletionStatus.COMPLETION_COMPLETE_PASS instead. | ||||
|      */ | ||||
|     static readonly COMPLETION_COMPLETE_PASS = 2; | ||||
|     /** | ||||
|      * @deprecated since 4.0, use CoreCourseModuleCompletionStatus.COMPLETION_COMPLETE_FAIL instead. | ||||
|      */ | ||||
|     static readonly COMPLETION_COMPLETE_FAIL = 3; | ||||
| 
 | ||||
|     static readonly COMPONENT = 'CoreCourse'; | ||||
| 
 | ||||
|     readonly CORE_MODULES = [ | ||||
| @ -863,24 +833,6 @@ export class CoreCourseProvider { | ||||
|         return path + moduleName + '.svg'; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Get the section ID a module belongs to. | ||||
|      * | ||||
|      * @param moduleId The module ID. | ||||
|      * @param siteId Site ID. If not defined, current site. | ||||
|      * @returns Promise resolved with the section ID. | ||||
|      * @deprecated since 4.0. | ||||
|      */ | ||||
|     async getModuleSectionId(moduleId: number, siteId?: string): Promise<number> { | ||||
|         // Try to get the section using getModuleBasicInfo.
 | ||||
|         const module = await CoreCourse.getModuleBasicInfo( | ||||
|             moduleId, | ||||
|             { siteId, readingStrategy: CoreSitesReadingStrategy.PREFER_CACHE }, | ||||
|         ); | ||||
| 
 | ||||
|         return module.section; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Return a specific section. | ||||
|      * | ||||
| @ -1829,15 +1781,6 @@ type CoreCourseGetCourseModuleWSResponse = { | ||||
|     warnings?: CoreWSExternalWarning[]; | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
|  * Course module data returned by the WS with course added. | ||||
|  * | ||||
|  * @deprecated since 4.0. Use CoreCourseModuleData instead. | ||||
|  */ | ||||
| export type CoreCourseWSModule = CoreCourseGetContentsWSModule & { | ||||
|     course: number; // The course id.
 | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
|  * Module completion data. | ||||
|  */ | ||||
|  | ||||
| @ -57,24 +57,6 @@ export interface CoreCourseFormatHandler extends CoreDelegateHandler { | ||||
|      */ | ||||
|     displayBlocks?(course: CoreCourseAnyCourseData): boolean; | ||||
| 
 | ||||
|     /** | ||||
|      * Whether the option to enable section/module download should be displayed. | ||||
|      * | ||||
|      * @param course The course to check. | ||||
|      * @returns Whether the option to enable section/module download should be displayed. | ||||
|      * @deprecated since 4.0 Not used anymore because prefetch has been moved to storage manager. | ||||
|      */ | ||||
|     displayEnableDownload?(course: CoreCourseAnyCourseData): boolean; | ||||
| 
 | ||||
|     /** | ||||
|      * Whether the default course index should be displayed. Defaults to true. | ||||
|      * | ||||
|      * @param course The course to check. | ||||
|      * @returns Whether the default course index should be displayed. | ||||
|      * @deprecated since 4.0. Please use displayCourseIndex instead. | ||||
|      */ | ||||
|     displaySectionSelector?(course: CoreCourseAnyCourseData): boolean; | ||||
| 
 | ||||
|     /** | ||||
|      * Whether the default section selector should be displayed. Defaults to true. | ||||
|      * | ||||
|  | ||||
| @ -77,16 +77,6 @@ export class CoreCourseModulePrefetchDelegateService extends CoreDelegate<CoreCo | ||||
|         }, CoreSites.getCurrentSiteId()); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Check if current site can check updates using core_course_check_updates. | ||||
|      * | ||||
|      * @returns True if can check updates, false otherwise. | ||||
|      * @deprecated since 4.0. | ||||
|      */ | ||||
|     canCheckUpdates(): boolean { | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Check if a certain module can use core_course_check_updates. | ||||
|      * | ||||
| @ -705,8 +695,7 @@ export class CoreCourseModulePrefetchDelegateService extends CoreDelegate<CoreCo | ||||
|         await Promise.all(modules.map(async (module) => { | ||||
|             const handler = this.getPrefetchHandlerFor(module.modname); | ||||
| 
 | ||||
|             // eslint-disable-next-line deprecation/deprecation
 | ||||
|             if (!handler || (onlyToDisplay && handler.skipListStatus)) { | ||||
|             if (!handler) { | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
| @ -1364,14 +1353,6 @@ export interface CoreCourseModulePrefetchHandler extends CoreDelegateHandler { | ||||
|      */ | ||||
|     updatesNames?: RegExp; | ||||
| 
 | ||||
|     /** | ||||
|      * If true, this module will be treated as not downloadable when determining the status of a list of modules. The module will | ||||
|      * still be downloaded when downloading the section/course, it only affects whether the button should be displayed. | ||||
|      * | ||||
|      * @deprecated since 4.0. | ||||
|      */ | ||||
|     skipListStatus?: boolean; | ||||
| 
 | ||||
|     /** | ||||
|      * Get the download size of a module. | ||||
|      * | ||||
|  | ||||
| @ -1,60 +1,3 @@ | ||||
| <ion-card [attr.course-color]="course.color ? null : course.colorNumber"> | ||||
|     <div (click)="openCourse()" class="core-course-thumb" [class.core-course-color-img]="course.courseimage" | ||||
|         [style.background-color]="course.color"> | ||||
|         <img *ngIf="course.courseimage" [src]="course.courseimage" core-external-content alt="" /> | ||||
|     </div> | ||||
|     <ion-item button (click)="openCourse()" [attr.aria-label]="course.displayname || course.fullname" class="core-course-header" | ||||
|         [class.core-course-only-title]="!showAll || progress < 0 && completionUserTracked === false" detail="false"> | ||||
|         <ion-label class="ion-text-wrap core-course-title" | ||||
|             [class.core-course-with-buttons]="courseOptionMenuEnabled || (downloadCourseEnabled && showDownload)" | ||||
|             [class.core-course-with-spinner]="(downloadCourseEnabled && prefetchCourseData.icon == 'spinner') || showSpinner"> | ||||
|             <p *ngIf="course.categoryname || (course.displayname && course.shortname && course.fullname != course.displayname)" | ||||
|                 class="core-course-additional-info"> | ||||
|                 <span class="sr-only">{{ 'core.courses.aria:coursecategory' | translate }}</span> | ||||
|                 <span *ngIf="course.categoryname" class="core-course-category"> | ||||
|                     <core-format-text [text]="course.categoryname"></core-format-text> | ||||
|                 </span> | ||||
|                 <span *ngIf="course.categoryname && course.displayname && course.shortname && course.fullname != course.displayname" | ||||
|                     class="core-course-category"> | </span> | ||||
|                 <span *ngIf="course.displayname && course.shortname && course.fullname != course.displayname" class="core-course-shortname"> | ||||
|                     <core-format-text [text]="course.shortname" contextLevel="course" [contextInstanceId]="course.id"> | ||||
|                     </core-format-text> | ||||
|                 </span> | ||||
|             </p> | ||||
|             <p class="item-heading"> | ||||
|                 <ion-icon name="fas-star" *ngIf="isFavourite" [attr.aria-label]="'core.courses.favourite' | translate"> | ||||
|                 </ion-icon> | ||||
|                 <span class="sr-only" *ngIf="isFavourite">{{ 'core.courses.aria:favourite' | translate }}</span> | ||||
|                 <span class="sr-only">{{ 'core.courses.aria:coursename' | translate }}</span> | ||||
|                 <core-format-text [text]="course.fullname" contextLevel="course" [contextInstanceId]="course.id"></core-format-text> | ||||
|             </p> | ||||
|         </ion-label> | ||||
| 
 | ||||
|         <div class="core-button-spinner" *ngIf="downloadCourseEnabled && !courseOptionMenuEnabled && showDownload" slot="end"> | ||||
|             <core-download-refresh [status]="prefetchCourseData.status" [enabled]="downloadCourseEnabled" | ||||
|                 [statusTranslatable]="prefetchCourseData.statusTranslatable" [canTrustDownload]="false" | ||||
|                 [loading]="prefetchCourseData.loading" (action)="prefetchCourse()"></core-download-refresh> | ||||
|         </div> | ||||
| 
 | ||||
|         <div class="core-button-spinner" *ngIf="courseOptionMenuEnabled" slot="end"> | ||||
|             <!-- Download course spinner. --> | ||||
|             <ion-spinner *ngIf="(downloadCourseEnabled && prefetchCourseData.icon == 'spinner') || showSpinner" | ||||
|                 [attr.aria-label]="'core.loading' | translate"></ion-spinner> | ||||
| 
 | ||||
|             <!-- Downloaded icon. --> | ||||
|             <ion-icon *ngIf="downloadCourseEnabled && prefetchCourseData.downloadSucceeded && !showSpinner" class="core-icon-downloaded" | ||||
|                 name="fam-cloud-done" color="success" role="status" [attr.aria-label]="'core.downloaded' | translate"></ion-icon> | ||||
| 
 | ||||
|             <!-- Options menu. --> | ||||
|             <ion-button fill="clear" (click)="showCourseOptionsMenu($event)" *ngIf="!showSpinner" | ||||
|                 [attr.aria-label]="('core.displayoptions' | translate)"> | ||||
|                 <ion-icon name="ellipsis-vertical" slot="icon-only" aria-hidden="true"></ion-icon> | ||||
|             </ion-button> | ||||
|         </div> | ||||
|     </ion-item> | ||||
|     <ion-item *ngIf="showAll && progress >= 0 && completionUserTracked !== false" class="core-course-progress"> | ||||
|         <ion-label> | ||||
|             <core-progress-bar [progress]="progress" a11yText="core.courses.aria:courseprogress"></core-progress-bar> | ||||
|         </ion-label> | ||||
|     </ion-item> | ||||
| </ion-card> | ||||
| <core-courses-course-list-item [course]="course" class="core-course-progress" [showDownload]="showDownload" | ||||
|     [layout]="showAll ? 'card' : 'summarycard'"> | ||||
| </core-courses-course-list-item> | ||||
|  | ||||
| @ -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; | ||||
|             } | ||||
| 
 | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -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<void> { | ||||
|         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<void> { | ||||
|         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<void> { | ||||
|         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<void> { | ||||
|         e.preventDefault(); | ||||
|         e.stopPropagation(); | ||||
| 
 | ||||
|         const popoverData = await CoreDomUtils.openPopover<string>({ | ||||
|             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<void> { | ||||
|         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, | ||||
|             ); | ||||
| 
 | ||||
|             (<CoreEnrolledCourseDataWithExtraInfoAndOptions> 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<void> { | ||||
|         this.showSpinner = true; | ||||
| 
 | ||||
|         try { | ||||
|             await CoreCourses.setFavouriteCourse(this.course.id, favourite); | ||||
| 
 | ||||
|             (<CoreEnrolledCourseDataWithExtraInfoAndOptions> 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(); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  | ||||
| @ -70,16 +70,6 @@ export class CoreCoursesProvider { | ||||
|     protected userCoursesIds?: Set<number>; | ||||
|     protected downloadOptionsEnabled = false; | ||||
| 
 | ||||
|     /** | ||||
|      * Whether current site supports getting course options. | ||||
|      * | ||||
|      * @returns Whether current site supports getting course options. | ||||
|      * @deprecated since 4.0. | ||||
|      */ | ||||
|     canGetAdminAndNavOptions(): boolean { | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Get categories. They can be filtered by id. | ||||
|      * | ||||
| @ -602,26 +592,6 @@ export class CoreCoursesProvider { | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Check if get courses by field WS is available in a certain site. | ||||
|      * | ||||
|      * @returns Whether get courses by field is available. | ||||
|      * @deprecated since 4.0. | ||||
|      */ | ||||
|     isGetCoursesByFieldAvailable(): boolean { | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Check if get courses by field WS is available in a certain site, by site ID. | ||||
|      * | ||||
|      * @returns Promise resolved with boolean: whether get courses by field is available. | ||||
|      * @deprecated since 4.0. | ||||
|      */ | ||||
|     async isGetCoursesByFieldAvailableInSite(): Promise<boolean> { | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Get the navigation and administration options for the given courses. | ||||
|      * | ||||
| @ -1462,7 +1432,7 @@ export type CoreCourseGetCoursesData = CoreEnrolledCourseBasicData & { | ||||
|     /** | ||||
|      * Number of weeks/topics. | ||||
|      * | ||||
|      * @deprecated use courseformatoptions. This attribute is deprecated in moodle since 2.4 but still present. | ||||
|      * @deprecatedonmoodle since 2.4. Use courseformatoptions. This attribute is deprecated in moodle since 2.4 but still present. | ||||
|      */ | ||||
|     numsections?: number; | ||||
|     maxbytes?: number; // Largest size of file that can be uploaded into the course.
 | ||||
| @ -1470,7 +1440,7 @@ export type CoreCourseGetCoursesData = CoreEnrolledCourseBasicData & { | ||||
|     /** | ||||
|      * How the hidden sections in the course are displayed to students. | ||||
|      * | ||||
|      * @deprecated use courseformatoptions. This attribute is deprecated in moodle since 2.4 but still present. | ||||
|      * @deprecatedonmoodle since 2.4. Use courseformatoptions. This attribute is deprecated in moodle since 2.4 but still present. | ||||
|      */ | ||||
|     hiddensections?: number; | ||||
|     groupmode?: number; // No group, separate, visible.
 | ||||
|  | ||||
| @ -60,26 +60,6 @@ export class CoreFilterProvider { | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Returns whether or not WS get available in context is available. | ||||
|      * | ||||
|      * @returns Promise resolved with true if ws is available, false otherwise. | ||||
|      * @deprecated since 4.0. | ||||
|      */ | ||||
|     async canGetAvailableInContext(): Promise<boolean> { | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Returns whether or not WS get available in context is available in a certain site. | ||||
|      * | ||||
|      * @returns Promise resolved with true if ws is available, false otherwise. | ||||
|      * @deprecated since 4.0. | ||||
|      */ | ||||
|     canGetAvailableInContextInSite(): boolean { | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Returns whether or not we can get the available filters: the WS is available and the feature isn't disabled. | ||||
|      * | ||||
|  | ||||
| @ -60,49 +60,6 @@ export class CoreGradesHelperProvider { | ||||
|         this.logger = CoreLogger.getInstance('CoreGradesHelperProvider'); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Formats a row from the grades table te be rendered in a page. | ||||
|      * | ||||
|      * @param tableRow JSON object representing row of grades table data. | ||||
|      * @returns Formatted row object. | ||||
|      * @deprecated since 4.0. | ||||
|      */ | ||||
|     protected async formatGradeRow(tableRow: CoreGradesTableRow): Promise<CoreGradesFormattedRow> { | ||||
|         const row: CoreGradesFormattedRow = { | ||||
|             rowclass: '', | ||||
|         }; | ||||
|         for (const name in tableRow) { | ||||
|             const column: CoreGradesTableColumn = tableRow[name]; | ||||
| 
 | ||||
|             if (column.content === undefined || column.content === null) { | ||||
|                 continue; | ||||
|             } | ||||
| 
 | ||||
|             let content = String(column.content); | ||||
| 
 | ||||
|             if (name == 'itemname') { | ||||
|                 await this.setRowIconAndType(row, content); | ||||
| 
 | ||||
|                 row.link = this.getModuleLink(content); | ||||
|                 row.rowclass += column.class.indexOf('hidden') >= 0 ? ' hidden' : ''; | ||||
|                 row.rowclass += column.class.indexOf('dimmed_text') >= 0 ? ' dimmed_text' : ''; | ||||
| 
 | ||||
|                 content = content.replace(/<\/span>/gi, '\n'); | ||||
|                 content = CoreTextUtils.cleanTags(content); | ||||
|             } else { | ||||
|                 content = CoreTextUtils.replaceNewLines(content, '<br>'); | ||||
|             } | ||||
| 
 | ||||
|             if (content == ' ') { | ||||
|                 content = ''; | ||||
|             } | ||||
| 
 | ||||
|             row[name] = content.trim(); | ||||
|         } | ||||
| 
 | ||||
|         return row; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Formats a row from the grades table to be rendered in one table. | ||||
|      * | ||||
| @ -353,34 +310,6 @@ export class CoreGradesHelperProvider { | ||||
|         return someCoursesAreMissing; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Get an specific grade item. | ||||
|      * | ||||
|      * @param courseId ID of the course to get the grades from. | ||||
|      * @param gradeId Grade ID. | ||||
|      * @param userId ID of the user to get the grades from. If not defined use site's current user. | ||||
|      * @param siteId Site ID. If not defined, current site. | ||||
|      * @param ignoreCache True if it should ignore cached data (it will always fail in offline or server down). | ||||
|      * @returns Promise to be resolved when the grades are retrieved. | ||||
|      * @deprecated since 4.0. | ||||
|      */ | ||||
|     async getGradeItem( | ||||
|         courseId: number, | ||||
|         gradeId: number, | ||||
|         userId?: number, | ||||
|         siteId?: string, | ||||
|         ignoreCache: boolean = false, | ||||
|     ): Promise<CoreGradesFormattedRow | null> { | ||||
|         const grades = await CoreGrades.getCourseGradesTable(courseId, userId, siteId, ignoreCache); | ||||
| 
 | ||||
|         if (!grades) { | ||||
|             throw new CoreError('Couldn\'t get grade item'); | ||||
|         } | ||||
| 
 | ||||
|         // eslint-disable-next-line deprecation/deprecation
 | ||||
|         return this.getGradesTableRow(grades, gradeId); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Returns the label of the selected grade. | ||||
|      * | ||||
| @ -460,65 +389,6 @@ export class CoreGradesHelperProvider { | ||||
|         return link; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Get a row from the grades table. | ||||
|      * | ||||
|      * @param table JSON object representing a table with data. | ||||
|      * @param gradeId Grade Object identifier. | ||||
|      * @returns Formatted HTML table. | ||||
|      * @deprecated since 4.0. | ||||
|      */ | ||||
|     async getGradesTableRow(table: CoreGradesTable, gradeId: number): Promise<CoreGradesFormattedRow | null> { | ||||
|         if (table.tabledata) { | ||||
|             const selectedRow = table.tabledata.find( | ||||
|                 (row) => | ||||
|                     row.itemname && | ||||
|                     row.itemname.id && | ||||
|                     row.itemname.id.substring(0, 3) == 'row' && | ||||
|                     parseInt(row.itemname.id.split('_')[1], 10) == gradeId, | ||||
|             ); | ||||
| 
 | ||||
|             if (selectedRow) { | ||||
|                 // eslint-disable-next-line deprecation/deprecation
 | ||||
|                 return await this.formatGradeRow(selectedRow); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         return null; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Get the rows related to a module from the grades table. | ||||
|      * | ||||
|      * @param table JSON object representing a table with data. | ||||
|      * @param moduleId Grade Object identifier. | ||||
|      * @returns Formatted HTML table. | ||||
|      * @deprecated since 4.0. | ||||
|      */ | ||||
|     async getModuleGradesTableRows(table: CoreGradesTable, moduleId: number): Promise<CoreGradesFormattedRow[]> { | ||||
|         if (!table.tabledata) { | ||||
|             return []; | ||||
|         } | ||||
| 
 | ||||
|         // Find href containing "/mod/xxx/xxx.php".
 | ||||
|         const regex = /href="([^"]*\/mod\/[^"|^/]*\/[^"|^.]*\.php[^"]*)/; | ||||
| 
 | ||||
|         return Promise.all(table.tabledata.filter((row) => { | ||||
|             if (row.itemname && row.itemname.content) { | ||||
|                 const matches = row.itemname.content.match(regex); | ||||
| 
 | ||||
|                 if (matches && matches.length) { | ||||
|                     const hrefParams = CoreUrlUtils.extractUrlParams(matches[1]); | ||||
| 
 | ||||
|                     return hrefParams && parseInt(hrefParams.id) === moduleId; | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             return false; | ||||
|         // eslint-disable-next-line deprecation/deprecation
 | ||||
|         }).map((row) => this.formatGradeRow(row))); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Get module grades to display. | ||||
|      * | ||||
|  | ||||
| @ -342,16 +342,6 @@ export class CoreGradesProvider { | ||||
|         return !(course && course.showgrades !== undefined && !course.showgrades); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Returns whether or not WS Grade Items is available. | ||||
|      * | ||||
|      * @returns True if ws is available, false otherwise. | ||||
|      * @deprecated since 4.0. | ||||
|      */ | ||||
|     async isGradeItemsAvailable(): Promise<boolean> { | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Log Course grades view in Moodle. | ||||
|      * | ||||
|  | ||||
| @ -44,16 +44,6 @@ export class CoreRatingProvider { | ||||
|     static readonly AGGREGATE_CHANGED_EVENT = 'core_rating_aggregate_changed'; | ||||
|     static readonly RATING_SAVED_EVENT = 'core_rating_rating_saved'; | ||||
| 
 | ||||
|     /** | ||||
|      * Returns whether the web serivce to add ratings is available. | ||||
|      * | ||||
|      * @returns If WS is available. | ||||
|      * @deprecated since 4.0. | ||||
|      */ | ||||
|     isAddRatingWSAvailable(): boolean { | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Add a rating to an item. | ||||
|      * | ||||
|  | ||||
| @ -14,7 +14,7 @@ | ||||
| 
 | ||||
| import { Component, OnDestroy, OnInit } from '@angular/core'; | ||||
| import { IonRefresher } from '@ionic/angular'; | ||||
| import { ActivatedRoute, Params } from '@angular/router'; | ||||
| import { ActivatedRoute } from '@angular/router'; | ||||
| 
 | ||||
| import { CoreSite, CoreSiteConfig } from '@classes/site'; | ||||
| import { CoreCourse, CoreCourseWSSection } from '@features/course/services/course'; | ||||
| @ -89,14 +89,7 @@ export class CoreSiteHomeIndexPage implements OnInit, OnDestroy { | ||||
| 
 | ||||
|         const module = CoreNavigator.getRouteParam<CoreCourseModuleData>('module'); | ||||
|         if (module) { | ||||
|             let modNavOptions = CoreNavigator.getRouteParam<CoreNavigationOptions>('modNavOptions'); | ||||
|             if (!modNavOptions) { | ||||
|                 // Fallback to old way of passing params. @deprecated since 4.0.
 | ||||
|                 const modParams = CoreNavigator.getRouteParam<Params>('modParams'); | ||||
|                 if (modParams) { | ||||
|                     modNavOptions = { params: modParams }; | ||||
|                 } | ||||
|             } | ||||
|             const modNavOptions = CoreNavigator.getRouteParam<CoreNavigationOptions>('modNavOptions'); | ||||
|             CoreCourseHelper.openModule(module, this.siteHomeId, { modNavOptions }); | ||||
|         } | ||||
| 
 | ||||
|  | ||||
| @ -40,8 +40,7 @@ export class CoreSitePluginsCourseFormatHandler extends CoreSitePluginsBaseHandl | ||||
|      */ | ||||
|     displayCourseIndex(): boolean { | ||||
|         // Use displaysectionselector while is not completely deprecated.
 | ||||
|         // eslint-disable-next-line deprecation/deprecation
 | ||||
|         return this.handlerSchema.displaycourseindex ?? this.handlerSchema.displaysectionselector ?? true; | ||||
|         return this.handlerSchema.displaycourseindex ?? true; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | ||||
| @ -12,11 +12,11 @@ | ||||
| // See the License for the specific language governing permissions and
 | ||||
| // limitations under the License.
 | ||||
| 
 | ||||
| import { Component, OnChanges, Input, ViewChild, Output, EventEmitter, HostBinding } from '@angular/core'; | ||||
| import { Component, OnChanges, Input, ViewChild, HostBinding } from '@angular/core'; | ||||
| import { IonRefresher } from '@ionic/angular'; | ||||
| 
 | ||||
| import { CoreCourseFormatComponent } from '@features/course/components/course-format/course-format'; | ||||
| import { CoreCourseModuleCompletionData, CoreCourseSection } from '@features/course/services/course-helper'; | ||||
| import { CoreCourseSection } from '@features/course/services/course-helper'; | ||||
| import { CoreCourseFormatDelegate } from '@features/course/services/format-delegate'; | ||||
| import { CoreCourseAnyCourseData } from '@features/courses/services/courses'; | ||||
| import { CoreSitePlugins, CoreSitePluginsContent } from '@features/siteplugins/services/siteplugins'; | ||||
| @ -37,12 +37,6 @@ export class CoreSitePluginsCourseFormatComponent implements OnChanges { | ||||
|     @Input() initialSectionId?: number; // The section to load first (by ID).
 | ||||
|     @Input() initialSectionNumber?: number; // The section to load first (by number).
 | ||||
|     @Input() moduleId?: number; // The module ID to scroll to. Must be inside the initial selected section.
 | ||||
|     /** | ||||
|      * Notify when any module completion changes. | ||||
|      * | ||||
|      * @deprecated since 4.0. Use CoreEvents instead. | ||||
|      */ | ||||
|     @Output() completionChanged = new EventEmitter<CoreCourseModuleCompletionData>(); | ||||
| 
 | ||||
|     // Special input, allows access to the parent instance properties and methods.
 | ||||
|     // Please notice that all the other inputs/outputs are also accessible through this instance, so they could be removed.
 | ||||
| @ -87,8 +81,6 @@ export class CoreSitePluginsCourseFormatComponent implements OnChanges { | ||||
|             initialSectionId: this.initialSectionId, | ||||
|             initialSectionNumber: this.initialSectionNumber, | ||||
|             moduleId: this.moduleId, | ||||
|             // eslint-disable-next-line deprecation/deprecation
 | ||||
|             completionChanged: this.completionChanged, | ||||
|             coreCourseFormatComponent: this.coreCourseFormatComponent, | ||||
|         }; | ||||
|     } | ||||
|  | ||||
| @ -12,9 +12,7 @@ | ||||
| // See the License for the specific language governing permissions and
 | ||||
| // limitations under the License.
 | ||||
| 
 | ||||
| import { CoreConstants } from '@/core/constants'; | ||||
| import { Component, OnInit, OnDestroy, Input, ViewChild, HostBinding } from '@angular/core'; | ||||
| import { CoreIonLoadingElement } from '@classes/ion-loading'; | ||||
| 
 | ||||
| import { CoreSiteWSPreSets } from '@classes/site'; | ||||
| import { | ||||
| @ -22,12 +20,11 @@ import { | ||||
|     CoreCourseModuleSummaryComponent, | ||||
| } from '@features/course/components/module-summary/module-summary'; | ||||
| import { CoreCourse } from '@features/course/services/course'; | ||||
| import { CoreCourseHelper, CoreCourseModuleData } from '@features/course/services/course-helper'; | ||||
| import { CoreCourseModuleData } from '@features/course/services/course-helper'; | ||||
| import { | ||||
|     CoreCourseModuleDelegate, | ||||
|     CoreCourseModuleMainComponent, | ||||
| } from '@features/course/services/module-delegate'; | ||||
| import { CoreCourseModulePrefetchDelegate } from '@features/course/services/module-prefetch-delegate'; | ||||
| import { | ||||
|     CoreSitePlugins, | ||||
|     CoreSitePluginsContent, | ||||
| @ -61,31 +58,6 @@ export class CoreSitePluginsModuleIndexComponent implements OnInit, OnDestroy, C | ||||
|     preSets?: CoreSiteWSPreSets; | ||||
|     description?: string; | ||||
| 
 | ||||
|     /** | ||||
|      * @deprecated since 4.0, use module.url instead. | ||||
|      */ | ||||
|     externalUrl?: string; | ||||
|     /** | ||||
|      * @deprecated since 4.0. It won't be populated anymore. | ||||
|      */ | ||||
|     refreshIcon = CoreConstants.ICON_REFRESH; | ||||
|     /** | ||||
|      * @deprecated since 4.0. It won't be populated anymore. | ||||
|      */ | ||||
|     prefetchStatus?: string; | ||||
|     /** | ||||
|      * @deprecated since 4.0. It won't be populated anymore. | ||||
|      */ | ||||
|     prefetchStatusIcon?: string; | ||||
|     /** | ||||
|      * @deprecated since 4.0. It won't be populated anymore. | ||||
|      */ | ||||
|     prefetchText?: string; | ||||
|     /** | ||||
|      * @deprecated since 4.0. It won't be populated anymore. | ||||
|      */ | ||||
|     size?: string; | ||||
| 
 | ||||
|     collapsibleFooterAppearOnBottom = true; | ||||
| 
 | ||||
|     displayOpenInBrowser = true; | ||||
| @ -142,8 +114,6 @@ export class CoreSitePluginsModuleIndexComponent implements OnInit, OnDestroy, C | ||||
| 
 | ||||
|         // Get the data for the context menu.
 | ||||
|         this.description = this.module.description; | ||||
|         // eslint-disable-next-line deprecation/deprecation
 | ||||
|         this.externalUrl = this.module.url; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
| @ -178,15 +148,6 @@ export class CoreSitePluginsModuleIndexComponent implements OnInit, OnDestroy, C | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Expand the description. | ||||
|      * | ||||
|      * @deprecated since 4.0. | ||||
|      */ | ||||
|     expandDescription(): void { | ||||
|         this.openModuleSummary(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Opens a module summary page. | ||||
|      */ | ||||
| @ -221,50 +182,7 @@ export class CoreSitePluginsModuleIndexComponent implements OnInit, OnDestroy, C | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Prefetch the module. | ||||
|      * | ||||
|      * @deprecated since 4.0. | ||||
|      */ | ||||
|     async prefetch(): Promise<void> { | ||||
|         try { | ||||
|             // We need to call getDownloadSize, the package might have been updated.
 | ||||
|             const size = await CoreCourseModulePrefetchDelegate.getModuleDownloadSize(this.module, this.courseId, true); | ||||
| 
 | ||||
|             await CoreDomUtils.confirmDownloadSize(size); | ||||
| 
 | ||||
|             await CoreCourseModulePrefetchDelegate.prefetchModule(this.module, this.courseId, true); | ||||
|         } catch (error) { | ||||
|             if (!this.isDestroyed) { | ||||
|                 CoreDomUtils.showErrorModalDefault(error, 'core.errordownloading', true); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Confirm and remove downloaded files. | ||||
|      * | ||||
|      * @deprecated since 4.0. | ||||
|      */ | ||||
|     async removeFiles(): Promise<void> { | ||||
|         let modal: CoreIonLoadingElement | undefined; | ||||
| 
 | ||||
|         try { | ||||
|             await CoreDomUtils.showDeleteConfirm('addon.storagemanager.confirmdeletedatafrom', { name: this.module.name }); | ||||
| 
 | ||||
|             modal = await CoreDomUtils.showModalLoading(); | ||||
| 
 | ||||
|             await CoreCourseHelper.removeModuleStoredData(this.module, this.courseId); | ||||
|         } catch (error) { | ||||
|             if (error) { | ||||
|                 CoreDomUtils.showErrorModal(error); | ||||
|             } | ||||
|         } finally { | ||||
|             modal?.dismiss(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Component destroyed. | ||||
|      * @inheritdoc | ||||
|      */ | ||||
|     ngOnDestroy(): void { | ||||
|         this.isDestroyed = true; | ||||
|  | ||||
| @ -391,16 +391,6 @@ export class CoreSitePluginsProvider { | ||||
|         await site.invalidateWsCacheForKey(this.getContentCacheKey(component, callback, args || {})); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Check if the get content WS is available. | ||||
|      * | ||||
|      * @returns If get content WS is available. | ||||
|      * @deprecated since 4.0 | ||||
|      */ | ||||
|     isGetContentAvailable(): boolean { | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Check if a handler is enabled for a certain course. | ||||
|      * | ||||
| @ -904,10 +894,6 @@ export type CoreSitePluginsCourseModuleHandlerData = CoreSitePluginsHandlerCommo | ||||
| export type CoreSitePluginsCourseFormatHandlerData = CoreSitePluginsHandlerCommonData & { | ||||
|     canviewallsections?: boolean; | ||||
|     displayenabledownload?: boolean; | ||||
|     /** | ||||
|      * @deprecated since 4.0. Use displaycourseindex instead. | ||||
|      */ | ||||
|     displaysectionselector?: boolean; | ||||
|     displaycourseindex?: boolean; | ||||
| }; | ||||
| 
 | ||||
|  | ||||
| @ -109,26 +109,6 @@ export class CoreUserProvider { | ||||
|         return !!site?.wsAvailable('core_enrol_search_users'); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Check if WS to update profile picture is available in site. | ||||
|      * | ||||
|      * @returns Promise resolved with boolean: whether it's available. | ||||
|      * @deprecated since 4.0. | ||||
|      */ | ||||
|     async canUpdatePicture(): Promise<boolean> { | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Check if WS to search participants is available in site. | ||||
|      * | ||||
|      * @returns Whether it's available. | ||||
|      * @deprecated since 4.0. | ||||
|      */ | ||||
|     canUpdatePictureInSite(): boolean { | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Change the given user profile picture. | ||||
|      * | ||||
|  | ||||
| @ -411,63 +411,6 @@ export class CoreSitesProvider { | ||||
|         return new CoreLoginError(options); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Check if a site exists. | ||||
|      * | ||||
|      * @param siteUrl URL of the site to check. | ||||
|      * @returns A promise to be resolved if the site exists. | ||||
|      * @deprecated since 4.0. Now the app calls uses tool_mobile_get_public_config to check if site exists. | ||||
|      */ | ||||
|     async siteExists(siteUrl: string): Promise<void> { | ||||
|         let data: CoreSitesLoginTokenResponse; | ||||
| 
 | ||||
|         // Use a valid path first.
 | ||||
|         siteUrl = CoreUrlUtils.removeUrlParams(siteUrl); | ||||
| 
 | ||||
|         try { | ||||
|             const lang = await CoreLang.getCurrentLanguage(CoreLangFormat.LMS); | ||||
| 
 | ||||
|             data = await Http.post(`${siteUrl}/login/token.php?lang=${lang}`, { appsitecheck: 1 }) | ||||
|                 .pipe(timeout(CoreWS.getRequestTimeout())) | ||||
|                 .toPromise(); | ||||
|         } catch (error) { | ||||
|             throw this.createCannotConnectLoginError(null, { | ||||
|                 supportConfig: await CoreUserGuestSupportConfig.forSite(siteUrl), | ||||
|                 errorcode: 'sitecheckfailed', | ||||
|                 errorDetails: CoreDomUtils.getErrorMessage(error) ?? undefined, | ||||
|             }); | ||||
|         } | ||||
| 
 | ||||
|         if (data === null) { | ||||
|             // Cannot connect.
 | ||||
|             throw this.createCannotConnectLoginError(null, { | ||||
|                 supportConfig: await CoreUserGuestSupportConfig.forSite(siteUrl), | ||||
|                 errorcode: 'appsitecheckfailed', | ||||
|                 errorDetails: 'A request to /login/token.php with appsitecheck=1 returned an empty response', | ||||
|             }); | ||||
|         } | ||||
| 
 | ||||
|         if (data.errorcode && (data.errorcode == 'enablewsdescription' || data.errorcode == 'requirecorrectaccess')) { | ||||
|             throw this.createCannotConnectLoginError(siteUrl, { | ||||
|                 supportConfig: await CoreUserGuestSupportConfig.forSite(siteUrl), | ||||
|                 critical: data.errorcode == 'enablewsdescription', | ||||
|                 errorcode: data.errorcode, | ||||
|                 errorDetails: data.error, | ||||
|             }); | ||||
|         } | ||||
| 
 | ||||
|         if (data.error && data.error == 'Web services must be enabled in Advanced features.') { | ||||
|             throw this.createCannotConnectLoginError(siteUrl, { | ||||
|                 supportConfig: await CoreUserGuestSupportConfig.forSite(siteUrl), | ||||
|                 critical: true, | ||||
|                 errorcode: 'enablewsdescription', | ||||
|                 errorDetails: data.error, | ||||
|             }); | ||||
|         } | ||||
| 
 | ||||
|         // Other errors are not being checked because invalid login will be always raised and we cannot differ them.
 | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Gets a user token from the server. | ||||
|      * | ||||
| @ -702,16 +645,6 @@ export class CoreSitesProvider { | ||||
|         return <string> Md5.hashAsciiStr(siteUrl + username); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Function for determine which service we should use (default or extended plugin). | ||||
|      * | ||||
|      * @returns The service shortname. | ||||
|      * @deprecated since 4.0. | ||||
|      */ | ||||
|     determineService(): string { | ||||
|         return CoreConstants.CONFIG.wsservice; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Visit a site link. | ||||
|      * | ||||
| @ -2184,13 +2117,6 @@ export type CoreSiteCheckResponse = { | ||||
|      */ | ||||
|     service: string; | ||||
| 
 | ||||
|     /** | ||||
|      * Code of the warning message to show to the user. | ||||
|      * | ||||
|      * @deprecated since 4.0. | ||||
|      */ | ||||
|     warning?: string; | ||||
| 
 | ||||
|     /** | ||||
|      * Site public config (if available). | ||||
|      */ | ||||
|  | ||||
| @ -49,8 +49,6 @@ import { CoreSites } from '@services/sites'; | ||||
| import { NavigationStart } from '@angular/router'; | ||||
| import { filter } from 'rxjs/operators'; | ||||
| import { Subscription } from 'rxjs'; | ||||
| import { CoreDirectivesRegistry } from '@singletons/directives-registry'; | ||||
| import { CoreDom } from '@singletons/dom'; | ||||
| import { CoreNetwork } from '@services/network'; | ||||
| import { CoreSiteError } from '@classes/errors/siteerror'; | ||||
| import { CoreUserSupport } from '@features/user/services/support'; | ||||
| @ -99,20 +97,6 @@ export class CoreDomUtilsProvider { | ||||
|         this.debugDisplay = debugDisplay != 0; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Equivalent to element.closest(). If the browser doesn't support element.closest, it will | ||||
|      * traverse the parents to achieve the same functionality. | ||||
|      * Returns the closest ancestor of the current element (or the current element itself) which matches the selector. | ||||
|      * | ||||
|      * @param element DOM Element. | ||||
|      * @param selector Selector to search. | ||||
|      * @returns Closest ancestor. | ||||
|      * @deprecated since 4.0. Not needed anymore since it's supported on both Android and iOS. Use closest instead. | ||||
|      */ | ||||
|     closest(element: Element | undefined | null, selector: string): Element | null { | ||||
|         return element?.closest(selector) ?? null; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * If the download size is higher than a certain threshold shows a confirm dialog. | ||||
|      * | ||||
| @ -396,91 +380,6 @@ export class CoreDomUtilsProvider { | ||||
|         return this.convertToElement(html).children[0].getAttribute(attribute); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Returns height of an element. | ||||
|      * | ||||
|      * @param element DOM element to measure. | ||||
|      * @param usePadding Whether to use padding to calculate the measure. | ||||
|      * @param useMargin Whether to use margin to calculate the measure. | ||||
|      * @param useBorder Whether to use borders to calculate the measure. | ||||
|      * @param innerMeasure If inner measure is needed: padding, margin or borders will be substracted. | ||||
|      * @returns Height in pixels. | ||||
|      * @deprecated since 4.0 Use getBoundingClientRect.height instead. | ||||
|      */ | ||||
|     getElementHeight( | ||||
|         element: HTMLElement, | ||||
|         usePadding?: boolean, | ||||
|         useMargin?: boolean, | ||||
|         useBorder?: boolean, | ||||
|         innerMeasure?: boolean, | ||||
|     ): number { | ||||
|         // eslint-disable-next-line deprecation/deprecation
 | ||||
|         return this.getElementMeasure(element, false, usePadding, useMargin, useBorder, innerMeasure); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Returns height or width of an element. | ||||
|      * | ||||
|      * @param element DOM element to measure. | ||||
|      * @param getWidth Whether to get width or height. | ||||
|      * @param usePadding Whether to use padding to calculate the measure. | ||||
|      * @param useMargin Whether to use margin to calculate the measure. | ||||
|      * @param useBorder Whether to use borders to calculate the measure. | ||||
|      * @param innerMeasure If inner measure is needed: padding, margin or borders will be substracted. | ||||
|      * @returns Measure in pixels. | ||||
|      * @deprecated since 4.0. Use getBoundingClientRect.height or width instead. | ||||
|      */ | ||||
|     getElementMeasure( | ||||
|         element: HTMLElement, | ||||
|         getWidth?: boolean, | ||||
|         usePadding?: boolean, | ||||
|         useMargin?: boolean, | ||||
|         useBorder?: boolean, | ||||
|         innerMeasure?: boolean, | ||||
|     ): number { | ||||
|         const offsetMeasure = getWidth ? 'offsetWidth' : 'offsetHeight'; | ||||
|         const measureName = getWidth ? 'width' : 'height'; | ||||
|         const clientMeasure = getWidth ? 'clientWidth' : 'clientHeight'; | ||||
|         const priorSide = getWidth ? 'Left' : 'Top'; | ||||
|         const afterSide = getWidth ? 'Right' : 'Bottom'; | ||||
|         let measure = element[offsetMeasure] || element[measureName] || element[clientMeasure] || 0; | ||||
| 
 | ||||
|         // Measure not correctly taken.
 | ||||
|         if (measure <= 0) { | ||||
|             const style = getComputedStyle(element); | ||||
|             if (style?.display == '') { | ||||
|                 element.style.display = 'inline-block'; | ||||
|                 measure = element[offsetMeasure] || element[measureName] || element[clientMeasure] || 0; | ||||
|                 element.style.display = ''; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         if (usePadding || useMargin || useBorder) { | ||||
|             const computedStyle = getComputedStyle(element); | ||||
|             let surround = 0; | ||||
| 
 | ||||
|             if (usePadding) { | ||||
|                 surround += this.getComputedStyleMeasure(computedStyle, 'padding' + priorSide) + | ||||
|                     this.getComputedStyleMeasure(computedStyle, 'padding' + afterSide); | ||||
|             } | ||||
|             if (useMargin) { | ||||
|                 surround += this.getComputedStyleMeasure(computedStyle, 'margin' + priorSide) + | ||||
|                     this.getComputedStyleMeasure(computedStyle, 'margin' + afterSide); | ||||
|             } | ||||
|             if (useBorder) { | ||||
|                 surround += this.getComputedStyleMeasure(computedStyle, 'border' + priorSide + 'Width') + | ||||
|                     this.getComputedStyleMeasure(computedStyle, 'border' + afterSide + 'Width'); | ||||
|             } | ||||
|             if (innerMeasure) { | ||||
|                 measure = measure > surround ? measure - surround : 0; | ||||
|             } else { | ||||
|                 measure += surround; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         return measure; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Returns the computed style measure or 0 if not found or NaN. | ||||
|      * | ||||
| @ -492,62 +391,6 @@ export class CoreDomUtilsProvider { | ||||
|         return parseInt(style[measure], 10) || 0; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Returns width of an element. | ||||
|      * | ||||
|      * @param element DOM element to measure. | ||||
|      * @param usePadding Whether to use padding to calculate the measure. | ||||
|      * @param useMargin Whether to use margin to calculate the measure. | ||||
|      * @param useBorder Whether to use borders to calculate the measure. | ||||
|      * @param innerMeasure If inner measure is needed: padding, margin or borders will be substracted. | ||||
|      * @returns Width in pixels. | ||||
|      * @deprecated since 4.0. Use getBoundingClientRect.width instead. | ||||
|      */ | ||||
|     getElementWidth( | ||||
|         element: HTMLElement, | ||||
|         usePadding?: boolean, | ||||
|         useMargin?: boolean, | ||||
|         useBorder?: boolean, | ||||
|         innerMeasure?: boolean, | ||||
|     ): number { | ||||
|         // eslint-disable-next-line deprecation/deprecation
 | ||||
|         return this.getElementMeasure(element, true, usePadding, useMargin, useBorder, innerMeasure); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Retrieve the position of a element relative to another element. | ||||
|      * | ||||
|      * @param element Element to search in. | ||||
|      * @param selector Selector to find the element to gets the position. | ||||
|      * @param positionParentClass Parent Class where to stop calculating the position. Default inner-scroll. | ||||
|      * @returns positionLeft, positionTop of the element relative to. | ||||
|      * @deprecated since 4.0. Use CoreDom.getRelativeElementPosition instead. | ||||
|      */ | ||||
|     getElementXY(element: HTMLElement, selector?: string, positionParentClass = 'inner-scroll'): [number, number] | null { | ||||
|         if (selector) { | ||||
|             const foundElement = element.querySelector<HTMLElement>(selector); | ||||
|             if (!foundElement) { | ||||
|                 // Element not found.
 | ||||
|                 return null; | ||||
|             } | ||||
| 
 | ||||
|             element = foundElement; | ||||
|         } | ||||
| 
 | ||||
|         const parent = element.closest<HTMLElement>(`.${positionParentClass}`); | ||||
|         if (!parent) { | ||||
|             return null; | ||||
|         } | ||||
| 
 | ||||
|         const position = CoreDom.getRelativeElementPosition(element, parent); | ||||
| 
 | ||||
|         // Calculate the top and left positions.
 | ||||
|         return [ | ||||
|             Math.ceil(position.x), | ||||
|             Math.ceil(position.y), | ||||
|         ]; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Given a message, it deduce if it's a network error. | ||||
|      * | ||||
| @ -639,19 +482,6 @@ export class CoreDomUtilsProvider { | ||||
|         return message; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Retrieve component/directive instance. | ||||
|      * Please use this function only if you cannot retrieve the instance using parent/child methods: ViewChild (or similar) | ||||
|      * or Angular's injection. | ||||
|      * | ||||
|      * @param element The root element of the component/directive. | ||||
|      * @returns The instance, undefined if not found. | ||||
|      * @deprecated since 4.0. Use CoreDirectivesRegistry instead. | ||||
|      */ | ||||
|     getInstanceByElement<T = unknown>(element: Element): T | undefined { | ||||
|         return CoreDirectivesRegistry.resolve<T>(element) ?? undefined; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Check whether an error is an error caused because the user canceled a showConfirm. | ||||
|      * | ||||
| @ -672,36 +502,6 @@ export class CoreDomUtilsProvider { | ||||
|         return error instanceof CoreSilentError; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Wait an element to exists using the findFunction. | ||||
|      * | ||||
|      * @param findFunction The function used to find the element. | ||||
|      * @param retries Number of retries before giving up. | ||||
|      * @param retryAfter Milliseconds to wait before retrying if the element wasn't found. | ||||
|      * @returns Resolved if found, rejected if too many tries. | ||||
|      * @deprecated since 4.0. Use CoreDom.waitToBeInsideElement instead. | ||||
|      */ | ||||
|     async waitElementToExist( | ||||
|         findFunction: () => HTMLElement | null, | ||||
|         retries: number = 100, | ||||
|         retryAfter: number = 100, | ||||
|     ): Promise<HTMLElement> { | ||||
|         const element = findFunction(); | ||||
| 
 | ||||
|         if (!element && retries === 0) { | ||||
|             throw Error('Element not found'); | ||||
|         } | ||||
| 
 | ||||
|         if (!element) { | ||||
|             await CoreUtils.wait(retryAfter); | ||||
| 
 | ||||
|             // eslint-disable-next-line deprecation/deprecation
 | ||||
|             return this.waitElementToExist(findFunction, retries - 1); | ||||
|         } | ||||
| 
 | ||||
|         return element; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Handle bootstrap tooltips in a certain element. | ||||
|      * | ||||
| @ -853,28 +653,6 @@ export class CoreDomUtilsProvider { | ||||
|         return element.innerHTML; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Remove a component/directive instance using the DOM Element. | ||||
|      * | ||||
|      * @param element The root element of the component/directive. | ||||
|      * @deprecated since 4.0. It's no longer necessary to remove instances. | ||||
|      */ | ||||
|     // eslint-disable-next-line @typescript-eslint/no-unused-vars
 | ||||
|     removeInstanceByElement(element: Element): void { | ||||
|         //
 | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Remove a component/directive instance using the ID. | ||||
|      * | ||||
|      * @param id The ID to remove. | ||||
|      * @deprecated since 4.0. It's no longer necessary to remove instances. | ||||
|      */ | ||||
|     // eslint-disable-next-line @typescript-eslint/no-unused-vars
 | ||||
|     removeInstanceById(id: string): void { | ||||
|         //
 | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Search for certain classes in an element contents and replace them with the specified new values. | ||||
|      * | ||||
| @ -998,67 +776,6 @@ export class CoreDomUtilsProvider { | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Scroll to a certain element. | ||||
|      * | ||||
|      * @param content Not used anymore. | ||||
|      * @param element The element to scroll to. | ||||
|      * @param scrollParentClass Not used anymore. | ||||
|      * @param duration Duration of the scroll animation in milliseconds. | ||||
|      * @returns True if the element is found, false otherwise. | ||||
|      * @deprecated since 4.0. Use CoreDom.scrollToElement instead. | ||||
|      */ | ||||
|     scrollToElement(content: IonContent, element: HTMLElement, scrollParentClass?: string, duration?: number): boolean { | ||||
|         CoreDom.scrollToElement(element, undefined, { duration }); | ||||
| 
 | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Scroll to a certain element using a selector to find it. | ||||
|      * | ||||
|      * @param container The element that contains the element that must be scrolled. | ||||
|      * @param content Not used anymore. | ||||
|      * @param selector Selector to find the element to scroll to. | ||||
|      * @param scrollParentClass Not used anymore. | ||||
|      * @param duration Duration of the scroll animation in milliseconds. | ||||
|      * @returns True if the element is found, false otherwise. | ||||
|      * @deprecated since 4.0. Use CoreDom.scrollToElement instead. | ||||
|      */ | ||||
|     scrollToElementBySelector( | ||||
|         container: HTMLElement | null, | ||||
|         content: unknown | null, | ||||
|         selector: string, | ||||
|         scrollParentClass?: string, | ||||
|         duration?: number, | ||||
|     ): boolean { | ||||
|         if (!container || !content) { | ||||
|             return false; | ||||
|         } | ||||
| 
 | ||||
|         CoreDom.scrollToElement(container, selector, { duration }); | ||||
| 
 | ||||
|         return true; | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Search for an input with error (core-input-error directive) and scrolls to it if found. | ||||
|      * | ||||
|      * @param container The element that contains the element that must be scrolled. | ||||
|      * @returns True if the element is found, false otherwise. | ||||
|      * @deprecated since 4.0. Use CoreDom.scrollToInputError instead. | ||||
|      */ | ||||
|     scrollToInputError(container: HTMLElement | null): boolean { | ||||
|         if (!container) { | ||||
|             return false; | ||||
|         } | ||||
| 
 | ||||
|         CoreDom.scrollToInputError(container); | ||||
| 
 | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Set whether debug messages should be displayed. | ||||
|      * | ||||
| @ -1669,17 +1386,6 @@ export class CoreDomUtilsProvider { | ||||
|         return loader; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Stores a component/directive instance. | ||||
|      * | ||||
|      * @param element The root element of the component/directive. | ||||
|      * @param instance The instance to store. | ||||
|      * @deprecated since 4.0. Use CoreDirectivesRegistry instead. | ||||
|      */ | ||||
|     storeInstanceByElement(element: Element, instance: unknown): void { | ||||
|         CoreDirectivesRegistry.register(element, instance); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Check if an element supports input via keyboard. | ||||
|      * | ||||
|  | ||||
| @ -298,18 +298,6 @@ export class CoreTextUtilsProvider { | ||||
|         return text; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Concatenate two paths, adding a slash between them if needed. | ||||
|      * | ||||
|      * @param leftPath Left path. | ||||
|      * @param rightPath Right path. | ||||
|      * @returns Concatenated path. | ||||
|      * @deprecated since 4.0. Use CorePath instead. | ||||
|      */ | ||||
|     concatenatePaths(leftPath: string, rightPath: string): string { | ||||
|         return CorePath.concatenatePaths(leftPath, rightPath); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Convert some HTML as text into an HTMLElement. This HTML is put inside a div or a body. | ||||
|      * This function is the same as in DomUtils, but we cannot use that one because of circular dependencies. | ||||
|  | ||||
| @ -16,7 +16,6 @@ import { Injectable } from '@angular/core'; | ||||
| 
 | ||||
| import moment, { LongDateFormatKey } from 'moment-timezone'; | ||||
| import { makeSingleton, Translate } from '@singletons'; | ||||
| import { CoreTime } from '@singletons/time'; | ||||
| 
 | ||||
| /* | ||||
|  * "Utils" service with helper functions for date and time. | ||||
| @ -155,52 +154,6 @@ export class CoreTimeUtilsProvider { | ||||
|         return fixed; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Returns years, months, days, hours, minutes and seconds in a human readable format. | ||||
|      * | ||||
|      * @param seconds A number of seconds | ||||
|      * @param precision Number of elements to have in precision. | ||||
|      * @returns Seconds in a human readable format. | ||||
|      * @deprecated since 4.0. Use CoreTime.formatTime instead. | ||||
|      */ | ||||
|     formatTime(seconds: number, precision = 2): string { | ||||
|         return CoreTime.formatTime(seconds, precision); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Converts a number of seconds into a short human readable format: minutes and seconds, in fromat: 3' 27''. | ||||
|      * | ||||
|      * @param duration Seconds | ||||
|      * @returns Short human readable text. | ||||
|      * @deprecated since 4.0. Use CoreTime.formatTimeShort instead. | ||||
|      */ | ||||
|     formatTimeShort(duration: number): string { | ||||
|         return CoreTime.formatTimeShort(duration); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Returns hours, minutes and seconds in a human readable format. | ||||
|      * | ||||
|      * @param duration Duration in seconds | ||||
|      * @param precision Number of elements to have in precision. 0 or undefined to full precission. | ||||
|      * @returns Duration in a human readable format. | ||||
|      * @deprecated since 4.0. Use CoreTime.formatTime instead. | ||||
|      */ | ||||
|     formatDuration(duration: number, precision?: number): string { | ||||
|         return CoreTime.formatTime(duration, precision); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Returns duration in a short human readable format: minutes and seconds, in fromat: 3' 27''. | ||||
|      * | ||||
|      * @param duration Duration in seconds | ||||
|      * @returns Duration in a short human readable format. | ||||
|      * @deprecated since 4.0. Use CoreTime.formatTimeShort instead. | ||||
|      */ | ||||
|     formatDurationShort(duration: number): string { | ||||
|         return CoreTime.formatTimeShort(duration); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Return the current timestamp in a "readable" format: YYYYMMDDHHmmSS. | ||||
|      * | ||||
|  | ||||
| @ -39,8 +39,6 @@ export interface CoreEventsData { | ||||
|     [CoreEvents.SITE_ADDED]: CoreEventSiteAddedData; | ||||
|     [CoreEvents.SITE_DELETED]: CoreSite; | ||||
|     [CoreEvents.SESSION_EXPIRED]: CoreEventSessionExpiredData; | ||||
|     // eslint-disable-next-line deprecation/deprecation
 | ||||
|     [CoreEvents.CORE_LOADING_CHANGED]: CoreEventLoadingChangedData; | ||||
|     [CoreEvents.COURSE_STATUS_CHANGED]: CoreEventCourseStatusChanged; | ||||
|     [CoreEvents.PACKAGE_STATUS_CHANGED]: CoreEventPackageStatusChanged; | ||||
|     [CoreEvents.USER_DELETED]: CoreEventUserDeletedData; | ||||
| @ -104,10 +102,6 @@ export class CoreEvents { | ||||
|     static readonly APP_LAUNCHED_URL = 'app_launched_url'; // App opened with a certain URL (custom URL scheme).
 | ||||
|     static readonly FILE_SHARED = 'file_shared'; | ||||
|     static readonly KEYBOARD_CHANGE = 'keyboard_change'; | ||||
|     /** | ||||
|      * @deprecated since 4.0. Use CoreDirectivesRegistry promises instead. | ||||
|      */ | ||||
|     static readonly CORE_LOADING_CHANGED = 'core_loading_changed'; | ||||
|     static readonly ORIENTATION_CHANGE = 'orientation_change'; | ||||
|     static readonly SEND_ON_ENTER_CHANGED = 'send_on_enter_changed'; | ||||
|     static readonly SELECT_COURSE_TAB = 'select_course_tab'; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user