diff --git a/src/addons/badges/services/handlers/push-click.ts b/src/addons/badges/services/handlers/push-click.ts index da50ffb03..5fa7b4c4e 100644 --- a/src/addons/badges/services/handlers/push-click.ts +++ b/src/addons/badges/services/handlers/push-click.ts @@ -14,7 +14,7 @@ import { Injectable } from '@angular/core'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { CorePushNotificationsClickHandler } from '@features/pushnotifications/services/push-delegate'; import { AddonBadges } from '../badges'; import { makeSingleton } from '@singletons'; diff --git a/src/addons/block/recentlyaccessedcourses/components/recentlyaccessedcourses/recentlyaccessedcourses.ts b/src/addons/block/recentlyaccessedcourses/components/recentlyaccessedcourses/recentlyaccessedcourses.ts index 148146f33..133f8f7b4 100644 --- a/src/addons/block/recentlyaccessedcourses/components/recentlyaccessedcourses/recentlyaccessedcourses.ts +++ b/src/addons/block/recentlyaccessedcourses/components/recentlyaccessedcourses/recentlyaccessedcourses.ts @@ -28,7 +28,7 @@ import { import { CoreCourseOptionsDelegate } from '@features/course/services/course-options-delegate'; import { AddonCourseCompletion } from '@addons/coursecompletion/services/coursecompletion'; import { CoreBlockBaseComponent } from '@features/block/classes/base-block-component'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { CoreSite } from '@classes/sites/site'; import { CoreSharedModule } from '@/core/shared.module'; import { CoreCoursesComponentsModule } from '@features/courses/components/components.module'; diff --git a/src/addons/block/recentlyaccesseditems/components/recentlyaccesseditems/recentlyaccesseditems.ts b/src/addons/block/recentlyaccesseditems/components/recentlyaccesseditems/recentlyaccesseditems.ts index 31d199720..b6d166d85 100644 --- a/src/addons/block/recentlyaccesseditems/components/recentlyaccesseditems/recentlyaccesseditems.ts +++ b/src/addons/block/recentlyaccesseditems/components/recentlyaccesseditems/recentlyaccesseditems.ts @@ -21,7 +21,7 @@ import { } from '../../services/recentlyaccesseditems'; import { CoreText } from '@singletons/text'; import { CoreLoadings } from '@services/loadings'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { CoreSharedModule } from '@/core/shared.module'; /** diff --git a/src/addons/block/starredcourses/components/starredcourses/starredcourses.ts b/src/addons/block/starredcourses/components/starredcourses/starredcourses.ts index 0bd36fa50..1b57099eb 100644 --- a/src/addons/block/starredcourses/components/starredcourses/starredcourses.ts +++ b/src/addons/block/starredcourses/components/starredcourses/starredcourses.ts @@ -23,7 +23,7 @@ import { import { CoreCourseOptionsDelegate } from '@features/course/services/course-options-delegate'; import { AddonCourseCompletion } from '@addons/coursecompletion/services/coursecompletion'; import { CoreBlockBaseComponent } from '@features/block/classes/base-block-component'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { CoreSite } from '@classes/sites/site'; import { AddonBlockStarredCourse, AddonBlockStarredCourses } from '../../services/starredcourses'; import { CoreSharedModule } from '@/core/shared.module'; diff --git a/src/addons/calendar/pages/edit-event/edit-event.ts b/src/addons/calendar/pages/edit-event/edit-event.ts index c95fde316..c3850c4a5 100644 --- a/src/addons/calendar/pages/edit-event/edit-event.ts +++ b/src/addons/calendar/pages/edit-event/edit-event.ts @@ -20,7 +20,7 @@ import { CoreSites } from '@services/sites'; import { CoreSync } from '@services/sync'; import { CoreDomUtils } from '@services/utils/dom'; import { CoreTimeUtils } from '@services/utils/time'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { CoreCategoryData, CoreCourses, CoreCourseSearchedData, CoreEnrolledCourseData } from '@features/courses/services/courses'; import { CoreEditorRichTextEditorComponent } from '@features/editor/components/rich-text-editor/rich-text-editor'; import { diff --git a/src/addons/calendar/services/calendar-sync.ts b/src/addons/calendar/services/calendar-sync.ts index d82383b8e..48169e731 100644 --- a/src/addons/calendar/services/calendar-sync.ts +++ b/src/addons/calendar/services/calendar-sync.ts @@ -17,7 +17,7 @@ import { CoreSyncBaseProvider, CoreSyncBlockedError } from '@classes/base-sync'; import { CoreNetwork } from '@services/network'; import { CoreEvents } from '@singletons/events'; import { CoreSites } from '@services/sites'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { AddonCalendar, AddonCalendarEvent, diff --git a/src/addons/competency/services/handlers/push-click.ts b/src/addons/competency/services/handlers/push-click.ts index b834cf4c0..678d44d85 100644 --- a/src/addons/competency/services/handlers/push-click.ts +++ b/src/addons/competency/services/handlers/push-click.ts @@ -19,7 +19,7 @@ import { CorePushNotificationsClickHandler } from '@features/pushnotifications/s import { CorePushNotificationsNotificationBasicData } from '@features/pushnotifications/services/pushnotifications'; import { CoreNavigator } from '@services/navigator'; import { CoreUrl } from '@singletons/url'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { makeSingleton } from '@singletons'; import { AddonCompetency } from '../competency'; import { CorePromiseUtils } from '@singletons/promise-utils'; diff --git a/src/addons/messages/pages/discussions-35/discussions.ts b/src/addons/messages/pages/discussions-35/discussions.ts index ad84ed038..2051d36d0 100644 --- a/src/addons/messages/pages/discussions-35/discussions.ts +++ b/src/addons/messages/pages/discussions-35/discussions.ts @@ -21,7 +21,7 @@ import { AddonMessagesMessageAreaContact, } from '../../services/messages'; import { CoreDomUtils } from '@services/utils/dom'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { ActivatedRoute, Params } from '@angular/router'; import { CorePushNotificationsNotificationBasicData } from '@features/pushnotifications/services/pushnotifications'; import { CorePushNotificationsDelegate } from '@features/pushnotifications/services/push-delegate'; diff --git a/src/addons/messages/pages/group-conversations/group-conversations.ts b/src/addons/messages/pages/group-conversations/group-conversations.ts index 00be18411..363307e01 100644 --- a/src/addons/messages/pages/group-conversations/group-conversations.ts +++ b/src/addons/messages/pages/group-conversations/group-conversations.ts @@ -33,7 +33,7 @@ import { Translate } from '@singletons'; import { Subscription } from 'rxjs'; import { CorePushNotificationsNotificationBasicData } from '@features/pushnotifications/services/pushnotifications'; import { ActivatedRoute, Params } from '@angular/router'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { CoreNavigator } from '@services/navigator'; import { CoreScreen } from '@services/screen'; import { CorePlatform } from '@services/platform'; diff --git a/src/addons/messages/services/handlers/mainmenu.ts b/src/addons/messages/services/handlers/mainmenu.ts index d10d79d02..c7a08eedd 100644 --- a/src/addons/messages/services/handlers/mainmenu.ts +++ b/src/addons/messages/services/handlers/mainmenu.ts @@ -20,7 +20,7 @@ import { CoreMainMenuHandler, CoreMainMenuHandlerToDisplay } from '@features/mai import { CoreCronHandler } from '@services/cron'; import { CoreSites } from '@services/sites'; import { CoreEvents } from '@singletons/events'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { CorePushNotificationsNotificationBasicData, } from '@features/pushnotifications/services/pushnotifications'; diff --git a/src/addons/messages/services/handlers/push-click.ts b/src/addons/messages/services/handlers/push-click.ts index dd20e1e3d..c915b88c0 100644 --- a/src/addons/messages/services/handlers/push-click.ts +++ b/src/addons/messages/services/handlers/push-click.ts @@ -16,7 +16,7 @@ import { Injectable } from '@angular/core'; import { CorePushNotificationsClickHandler } from '@features/pushnotifications/services/push-delegate'; import { CorePushNotificationsNotificationBasicData } from '@features/pushnotifications/services/pushnotifications'; import { CoreNavigator } from '@services/navigator'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { makeSingleton } from '@singletons'; import { AddonMessages } from '../messages'; import { AddonMessagesMainMenuHandlerService } from './mainmenu'; diff --git a/src/addons/mod/assign/components/submission/submission.ts b/src/addons/mod/assign/components/submission/submission.ts index 17283e4bd..ae4849e10 100644 --- a/src/addons/mod/assign/components/submission/submission.ts +++ b/src/addons/mod/assign/components/submission/submission.ts @@ -37,7 +37,7 @@ import { CoreTabsComponent } from '@components/tabs/tabs'; import { CoreTabComponent } from '@components/tabs/tab'; import { CoreSplitViewComponent } from '@components/split-view/split-view'; import { CoreGradesFormattedItem, CoreGradesHelper } from '@features/grades/services/grades-helper'; -import { CoreMenuItem, CoreUtils } from '@services/utils/utils'; +import { CoreMenuItem, CoreUtils } from '@singletons/utils'; import { AddonModAssignHelper, AddonModAssignSubmissionFormatted } from '../../services/assign-helper'; import { CoreDomUtils } from '@services/utils/dom'; import { Translate } from '@singletons'; diff --git a/src/addons/mod/assign/services/handlers/push-click.ts b/src/addons/mod/assign/services/handlers/push-click.ts index 56a568495..02b9231da 100644 --- a/src/addons/mod/assign/services/handlers/push-click.ts +++ b/src/addons/mod/assign/services/handlers/push-click.ts @@ -17,7 +17,7 @@ import { CoreCourseHelper } from '@features/course/services/course-helper'; import { CorePushNotificationsClickHandler } from '@features/pushnotifications/services/push-delegate'; import { CorePushNotificationsNotificationBasicData } from '@features/pushnotifications/services/pushnotifications'; import { CoreUrl } from '@singletons/url'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { makeSingleton } from '@singletons'; import { AddonModAssign } from '../assign'; import { ADDON_MOD_ASSIGN_FEATURE_NAME } from '../../constants'; diff --git a/src/addons/mod/data/pages/edit/edit.ts b/src/addons/mod/data/pages/edit/edit.ts index 87856bbe4..a24bcfa1a 100644 --- a/src/addons/mod/data/pages/edit/edit.ts +++ b/src/addons/mod/data/pages/edit/edit.ts @@ -23,7 +23,7 @@ import { CoreNavigator } from '@services/navigator'; import { CoreSites } from '@services/sites'; import { CoreDomUtils } from '@services/utils/dom'; import { CoreForms } from '@singletons/form'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { Translate } from '@singletons'; import { CoreEvents } from '@singletons/events'; import { AddonModDataComponentsCompileModule } from '../../components/components-compile.module'; diff --git a/src/addons/mod/feedback/pages/form/form.ts b/src/addons/mod/feedback/pages/form/form.ts index e4d45815b..446684fec 100644 --- a/src/addons/mod/feedback/pages/form/form.ts +++ b/src/addons/mod/feedback/pages/form/form.ts @@ -22,7 +22,7 @@ import { CoreNetwork } from '@services/network'; import { CoreNavigator } from '@services/navigator'; import { CoreSites, CoreSitesReadingStrategy } from '@services/sites'; import { CoreDomUtils } from '@services/utils/dom'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { NgZone, Translate } from '@singletons'; import { CoreEvents } from '@singletons/events'; import { Subscription } from 'rxjs'; diff --git a/src/addons/mod/feedback/services/feedback-helper.ts b/src/addons/mod/feedback/services/feedback-helper.ts index 80728c8d3..e6e88c46c 100644 --- a/src/addons/mod/feedback/services/feedback-helper.ts +++ b/src/addons/mod/feedback/services/feedback-helper.ts @@ -20,7 +20,7 @@ import { CoreSites, CoreSitesReadingStrategy } from '@services/sites'; import { CoreDomUtils } from '@services/utils/dom'; import { CoreFileHelper } from '@services/file-helper'; import { CoreTimeUtils } from '@services/utils/time'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { makeSingleton, Translate } from '@singletons'; import { AddonModFeedback, diff --git a/src/addons/mod/feedback/services/handlers/push-click.ts b/src/addons/mod/feedback/services/handlers/push-click.ts index d6ae6a840..a61ca33a4 100644 --- a/src/addons/mod/feedback/services/handlers/push-click.ts +++ b/src/addons/mod/feedback/services/handlers/push-click.ts @@ -17,7 +17,7 @@ import { CoreCourseHelper } from '@features/course/services/course-helper'; import { CorePushNotificationsClickHandler } from '@features/pushnotifications/services/push-delegate'; import { CorePushNotificationsNotificationBasicData } from '@features/pushnotifications/services/pushnotifications'; import { CoreUrl } from '@singletons/url'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { makeSingleton } from '@singletons'; import { AddonModFeedbackHelper } from '../feedback-helper'; diff --git a/src/addons/mod/forum/pages/discussion/discussion.ts b/src/addons/mod/forum/pages/discussion/discussion.ts index bafd3b355..df9779cb4 100644 --- a/src/addons/mod/forum/pages/discussion/discussion.ts +++ b/src/addons/mod/forum/pages/discussion/discussion.ts @@ -29,7 +29,7 @@ import { CoreNavigator } from '@services/navigator'; import { CoreScreen } from '@services/screen'; import { CoreSites } from '@services/sites'; import { CoreDomUtils } from '@services/utils/dom'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { NgZone, Translate } from '@singletons'; import { CoreDom } from '@singletons/dom'; import { CoreEventObserver, CoreEvents } from '@singletons/events'; diff --git a/src/addons/mod/forum/pages/new-discussion/new-discussion.ts b/src/addons/mod/forum/pages/new-discussion/new-discussion.ts index 227386113..ab009aa9f 100644 --- a/src/addons/mod/forum/pages/new-discussion/new-discussion.ts +++ b/src/addons/mod/forum/pages/new-discussion/new-discussion.ts @@ -31,7 +31,7 @@ import { CoreDomUtils } from '@services/utils/dom'; import { Translate } from '@singletons'; import { CoreSync } from '@services/sync'; import { AddonModForumDiscussionOptions, AddonModForumOffline } from '@addons/mod/forum/services/forum-offline'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { AddonModForumHelper } from '@addons/mod/forum/services/forum-helper'; import { CoreFileUploader } from '@features/fileuploader/services/fileuploader'; import { CoreText } from '@singletons/text'; diff --git a/src/addons/mod/forum/pages/search/search.ts b/src/addons/mod/forum/pages/search/search.ts index 934a85d4f..ddf2e48c5 100644 --- a/src/addons/mod/forum/pages/search/search.ts +++ b/src/addons/mod/forum/pages/search/search.ts @@ -28,7 +28,7 @@ import { CoreNavigator } from '@services/navigator'; import { CoreSites } from '@services/sites'; import { CoreDomUtils } from '@services/utils/dom'; import { CoreUrl } from '@singletons/url'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { Translate } from '@singletons'; import { CorePromiseUtils } from '@singletons/promise-utils'; diff --git a/src/addons/mod/forum/services/forum-helper.ts b/src/addons/mod/forum/services/forum-helper.ts index c796d23f3..783fff12d 100644 --- a/src/addons/mod/forum/services/forum-helper.ts +++ b/src/addons/mod/forum/services/forum-helper.ts @@ -20,7 +20,7 @@ import { CoreNetwork } from '@services/network'; import { CoreFile } from '@services/file'; import { CoreSites } from '@services/sites'; import { CoreTimeUtils } from '@services/utils/time'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { makeSingleton, Translate } from '@singletons'; import { AddonModForum, diff --git a/src/addons/mod/forum/services/forum-sync.ts b/src/addons/mod/forum/services/forum-sync.ts index bcc5f1134..9868c9cb7 100644 --- a/src/addons/mod/forum/services/forum-sync.ts +++ b/src/addons/mod/forum/services/forum-sync.ts @@ -22,7 +22,7 @@ import { CoreNetwork } from '@services/network'; import { CoreGroups } from '@services/groups'; import { CoreSites } from '@services/sites'; import { CoreSync, CoreSyncResult } from '@services/sync'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { makeSingleton, Translate } from '@singletons'; import { CoreEvents } from '@singletons/events'; import { diff --git a/src/addons/mod/forum/services/forum.ts b/src/addons/mod/forum/services/forum.ts index 12e9958e2..290c9ae24 100644 --- a/src/addons/mod/forum/services/forum.ts +++ b/src/addons/mod/forum/services/forum.ts @@ -25,7 +25,7 @@ import { CoreFileEntry } from '@services/file-helper'; import { CoreGroups } from '@services/groups'; import { CoreSitesCommonWSOptions, CoreSites, CoreSitesReadingStrategy } from '@services/sites'; import { CoreUrl } from '@singletons/url'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { CoreStatusWithWarningsWSResponse, CoreWSExternalFile, diff --git a/src/addons/mod/forum/services/handlers/push-click.ts b/src/addons/mod/forum/services/handlers/push-click.ts index 5923e1142..a2b0be78e 100644 --- a/src/addons/mod/forum/services/handlers/push-click.ts +++ b/src/addons/mod/forum/services/handlers/push-click.ts @@ -20,7 +20,7 @@ import { CoreNavigator } from '@services/navigator'; import { CorePushNotificationsClickHandler } from '@features/pushnotifications/services/push-delegate'; import { CorePushNotificationsNotificationBasicData } from '@features/pushnotifications/services/pushnotifications'; import { CoreUrl } from '@singletons/url'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { makeSingleton } from '@singletons'; import { isSafeNumber } from '@/core/utils/types'; diff --git a/src/addons/mod/lesson/services/handlers/push-click.ts b/src/addons/mod/lesson/services/handlers/push-click.ts index 6a63059be..f0a3d19b3 100644 --- a/src/addons/mod/lesson/services/handlers/push-click.ts +++ b/src/addons/mod/lesson/services/handlers/push-click.ts @@ -19,7 +19,7 @@ import { CoreGrades } from '@features/grades/services/grades'; import { CoreGradesHelper } from '@features/grades/services/grades-helper'; import { CorePushNotificationsClickHandler } from '@features/pushnotifications/services/push-delegate'; import { CorePushNotificationsNotificationBasicData } from '@features/pushnotifications/services/pushnotifications'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { makeSingleton } from '@singletons'; /** diff --git a/src/addons/mod/lesson/services/lesson-helper.ts b/src/addons/mod/lesson/services/lesson-helper.ts index 1bd5c7397..1f063887a 100644 --- a/src/addons/mod/lesson/services/lesson-helper.ts +++ b/src/addons/mod/lesson/services/lesson-helper.ts @@ -26,7 +26,7 @@ import { AddonModLessonGetPageDataWSResponse, } from './lesson'; import { CoreTime } from '@singletons/time'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { AddonModLessonPageSubtype } from '../constants'; import { convertTextToHTMLElement } from '@/core/utils/create-html-element'; diff --git a/src/addons/mod/lesson/services/lesson.ts b/src/addons/mod/lesson/services/lesson.ts index f20f3ae44..b877c636f 100644 --- a/src/addons/mod/lesson/services/lesson.ts +++ b/src/addons/mod/lesson/services/lesson.ts @@ -19,7 +19,7 @@ import { CoreCourseLogHelper } from '@features/course/services/log-helper'; import { CoreSites, CoreSitesCommonWSOptions, CoreSitesReadingStrategy } from '@services/sites'; import { convertTextToHTMLElement } from '@/core/utils/create-html-element'; import { CoreText } from '@singletons/text'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { CoreWSExternalFile, CoreWSExternalWarning } from '@services/ws'; import { makeSingleton, Translate } from '@singletons'; import { CoreEvents } from '@singletons/events'; diff --git a/src/addons/mod/page/components/index/index.ts b/src/addons/mod/page/components/index/index.ts index 4e63ead7b..2fb49068a 100644 --- a/src/addons/mod/page/components/index/index.ts +++ b/src/addons/mod/page/components/index/index.ts @@ -16,7 +16,7 @@ import { Component, OnInit, Optional } from '@angular/core'; import { CoreCourseModuleMainResourceComponent } from '@features/course/classes/main-resource-component'; import { CoreCourseContentsPage } from '@features/course/pages/contents/contents'; import { CoreText } from '@singletons/text'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { AddonModPagePage, AddonModPage } from '../../services/page'; import { AddonModPageHelper } from '../../services/page-helper'; import { ADDON_MOD_PAGE_COMPONENT } from '../../constants'; diff --git a/src/addons/mod/quiz/services/handlers/push-click.ts b/src/addons/mod/quiz/services/handlers/push-click.ts index 54e71a1aa..0b6279106 100644 --- a/src/addons/mod/quiz/services/handlers/push-click.ts +++ b/src/addons/mod/quiz/services/handlers/push-click.ts @@ -18,7 +18,7 @@ import { CoreCourseHelper } from '@features/course/services/course-helper'; import { CorePushNotificationsClickHandler } from '@features/pushnotifications/services/push-delegate'; import { CorePushNotificationsNotificationBasicData } from '@features/pushnotifications/services/pushnotifications'; import { CoreUrl } from '@singletons/url'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { makeSingleton } from '@singletons'; import { AddonModQuiz } from '../quiz'; import { AddonModQuizHelper } from '../quiz-helper'; diff --git a/src/addons/mod/quiz/services/quiz.ts b/src/addons/mod/quiz/services/quiz.ts index 98a3e06e3..938081dbb 100644 --- a/src/addons/mod/quiz/services/quiz.ts +++ b/src/addons/mod/quiz/services/quiz.ts @@ -30,7 +30,7 @@ import { CoreQuestionDelegate } from '@features/question/services/question-deleg import { CoreSites, CoreSitesCommonWSOptions, CoreSitesReadingStrategy } from '@services/sites'; import { convertTextToHTMLElement } from '@/core/utils/create-html-element'; import { CoreTimeUtils } from '@services/utils/time'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { CoreStatusWithWarningsWSResponse, CoreWSExternalFile, CoreWSExternalWarning } from '@services/ws'; import { makeSingleton, Translate } from '@singletons'; import { CoreLogger } from '@singletons/logger'; diff --git a/src/addons/mod/scorm/classes/data-model-12.ts b/src/addons/mod/scorm/classes/data-model-12.ts index 9e1bfa443..ff82db040 100644 --- a/src/addons/mod/scorm/classes/data-model-12.ts +++ b/src/addons/mod/scorm/classes/data-model-12.ts @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { CoreEvents } from '@singletons/events'; import { AddonModScorm, diff --git a/src/addons/mod/scorm/services/scorm-helper.ts b/src/addons/mod/scorm/services/scorm-helper.ts index c624f808c..adadfc273 100644 --- a/src/addons/mod/scorm/services/scorm-helper.ts +++ b/src/addons/mod/scorm/services/scorm-helper.ts @@ -17,7 +17,7 @@ import { CoreError } from '@classes/errors/error'; import { CoreCourseCommonModWSOptions } from '@features/course/services/course'; import { CoreSites } from '@services/sites'; import { CoreDomUtils } from '@services/utils/dom'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { makeSingleton, Translate } from '@singletons'; import { AddonModScorm, diff --git a/src/addons/mod/scorm/services/scorm-offline.ts b/src/addons/mod/scorm/services/scorm-offline.ts index 6fa4a36ed..7105aa947 100644 --- a/src/addons/mod/scorm/services/scorm-offline.ts +++ b/src/addons/mod/scorm/services/scorm-offline.ts @@ -18,7 +18,7 @@ import { CoreSites } from '@services/sites'; import { CoreSync } from '@services/sync'; import { CoreText } from '@singletons/text'; import { CoreTimeUtils } from '@services/utils/time'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { makeSingleton } from '@singletons'; import { CoreLogger } from '@singletons/logger'; import { diff --git a/src/addons/mod/workshop/components/assessment-strategy/assessment-strategy.ts b/src/addons/mod/workshop/components/assessment-strategy/assessment-strategy.ts index 2834b706e..d237d0482 100644 --- a/src/addons/mod/workshop/components/assessment-strategy/assessment-strategy.ts +++ b/src/addons/mod/workshop/components/assessment-strategy/assessment-strategy.ts @@ -22,7 +22,7 @@ import { CoreFileSession } from '@services/file-session'; import { CoreSites } from '@services/sites'; import { CoreSync } from '@services/sync'; import { CoreDomUtils } from '@services/utils/dom'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { Translate } from '@singletons'; import { CoreEventObserver, CoreEvents } from '@singletons/events'; import { CoreFormFields, CoreForms } from '@singletons/form'; diff --git a/src/addons/mod/workshop/services/workshop-helper.ts b/src/addons/mod/workshop/services/workshop-helper.ts index e78f9c61a..66ee315b7 100644 --- a/src/addons/mod/workshop/services/workshop-helper.ts +++ b/src/addons/mod/workshop/services/workshop-helper.ts @@ -20,7 +20,7 @@ import { CoreFile } from '@services/file'; import { CoreFileEntry } from '@services/file-helper'; import { CoreSites } from '@services/sites'; import { CoreText, CoreTextFormat } from '@singletons/text'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { makeSingleton, Translate } from '@singletons'; import { CoreFormFields } from '@singletons/form'; import { AddonModWorkshopAssessmentStrategyFieldErrors } from '../components/assessment-strategy/assessment-strategy'; diff --git a/src/addons/notifications/pages/list/list.ts b/src/addons/notifications/pages/list/list.ts index 9eb6ac843..b78a98c65 100644 --- a/src/addons/notifications/pages/list/list.ts +++ b/src/addons/notifications/pages/list/list.ts @@ -16,7 +16,7 @@ import { AfterViewInit, Component, OnDestroy, ViewChild } from '@angular/core'; import { Subscription } from 'rxjs'; import { CoreDomUtils } from '@services/utils/dom'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { CoreEventObserver, CoreEvents } from '@singletons/events'; import { AddonNotifications, AddonNotificationsNotificationMessageFormatted, AddonNotificationsProvider, diff --git a/src/addons/notifications/services/handlers/mainmenu.ts b/src/addons/notifications/services/handlers/mainmenu.ts index bf4e7accc..6dda0771b 100644 --- a/src/addons/notifications/services/handlers/mainmenu.ts +++ b/src/addons/notifications/services/handlers/mainmenu.ts @@ -15,7 +15,7 @@ import { Injectable } from '@angular/core'; import { CoreSites } from '@services/sites'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { makeSingleton } from '@singletons'; import { CoreEvents } from '@singletons/events'; import { CoreMainMenuHandler, CoreMainMenuHandlerData } from '@features/mainmenu/services/mainmenu-delegate'; diff --git a/src/addons/notifications/services/handlers/push-click.ts b/src/addons/notifications/services/handlers/push-click.ts index 77b1593cd..a46d4d273 100644 --- a/src/addons/notifications/services/handlers/push-click.ts +++ b/src/addons/notifications/services/handlers/push-click.ts @@ -15,7 +15,7 @@ import { Injectable } from '@angular/core'; import { CoreNavigator } from '@services/navigator'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { makeSingleton } from '@singletons'; import { CorePushNotificationsClickHandler } from '@features/pushnotifications/services/push-delegate'; import { CorePushNotificationsNotificationBasicData } from '@features/pushnotifications/services/pushnotifications'; diff --git a/src/addons/userprofilefield/checkbox/component/checkbox.ts b/src/addons/userprofilefield/checkbox/component/checkbox.ts index 22fef02d2..bd8f6d926 100644 --- a/src/addons/userprofilefield/checkbox/component/checkbox.ts +++ b/src/addons/userprofilefield/checkbox/component/checkbox.ts @@ -17,7 +17,7 @@ import { Validators, FormControl } from '@angular/forms'; import { AuthEmailSignupProfileField } from '@features/login/services/login-helper'; import { CoreUserProfileFieldBaseComponent } from '@features/user/classes/base-profilefield-component'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; /** * Directive to render a checkbox user profile field. diff --git a/src/addons/userprofilefield/datetime/component/datetime.ts b/src/addons/userprofilefield/datetime/component/datetime.ts index af78bef7e..4693ea429 100644 --- a/src/addons/userprofilefield/datetime/component/datetime.ts +++ b/src/addons/userprofilefield/datetime/component/datetime.ts @@ -16,7 +16,7 @@ import { FormControl, Validators } from '@angular/forms'; import { Component } from '@angular/core'; import { CoreTimeUtils } from '@services/utils/time'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { AuthEmailSignupProfileField } from '@features/login/services/login-helper'; import { CoreUserProfileField } from '@features/user/services/user'; import { CoreUserProfileFieldBaseComponent } from '@features/user/classes/base-profilefield-component'; diff --git a/src/addons/userprofilefield/text/component/text.ts b/src/addons/userprofilefield/text/component/text.ts index 00b8c487c..6dbee9657 100644 --- a/src/addons/userprofilefield/text/component/text.ts +++ b/src/addons/userprofilefield/text/component/text.ts @@ -16,7 +16,7 @@ import { Component } from '@angular/core'; import { AuthEmailSignupProfileField } from '@features/login/services/login-helper'; import { CoreUserProfileFieldBaseComponent } from '@features/user/classes/base-profilefield-component'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; /** * Directive to render a text user profile field. diff --git a/src/core/classes/items-management/list-items-manager.ts b/src/core/classes/items-management/list-items-manager.ts index a0de7591d..beb8594c4 100644 --- a/src/core/classes/items-management/list-items-manager.ts +++ b/src/core/classes/items-management/list-items-manager.ts @@ -18,7 +18,7 @@ import { Subscription } from 'rxjs'; import { CoreSplitViewComponent } from '@components/split-view/split-view'; import { CoreNavigator } from '@services/navigator'; import { CoreScreen } from '@services/screen'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { CoreRoutedItemsManagerSource } from './routed-items-manager-source'; import { CoreRoutedItemsManager } from './routed-items-manager'; diff --git a/src/core/classes/sites/authenticated-site.ts b/src/core/classes/sites/authenticated-site.ts index 3ca4a21ae..3d60d14f2 100644 --- a/src/core/classes/sites/authenticated-site.ts +++ b/src/core/classes/sites/authenticated-site.ts @@ -23,7 +23,7 @@ import { } from '@services/ws'; import { CoreToasts, ToastDuration } from '@services/toasts'; import { CoreText } from '@singletons/text'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { CoreCacheUpdateFrequency, CoreConstants, MINIMUM_MOODLE_VERSION, MOODLE_RELEASES } from '@/core/constants'; import { CoreError } from '@classes/errors/error'; import { CoreWSError } from '@classes/errors/wserror'; diff --git a/src/core/components/context-menu/context-menu.ts b/src/core/components/context-menu/context-menu.ts index 9d3f03900..44f1d470e 100644 --- a/src/core/components/context-menu/context-menu.ts +++ b/src/core/components/context-menu/context-menu.ts @@ -16,7 +16,7 @@ import { Component, Input, OnInit, OnDestroy, ElementRef, ChangeDetectorRef } fr import { Subject, Subscription } from 'rxjs'; import { auditTime } from 'rxjs/operators'; import { CorePopovers } from '@services/popovers'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { Translate } from '@singletons'; import { CoreContextMenuItemComponent } from './context-menu-item'; import { CoreDirectivesRegistry } from '@singletons/directives-registry'; diff --git a/src/core/components/loading/loading.ts b/src/core/components/loading/loading.ts index b97466f9e..fc38bea48 100644 --- a/src/core/components/loading/loading.ts +++ b/src/core/components/loading/loading.ts @@ -14,7 +14,7 @@ import { Component, Input, OnInit, OnChanges, SimpleChange, ElementRef, AfterViewInit, OnDestroy } from '@angular/core'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { CoreAnimations } from '@components/animations'; import { Translate } from '@singletons'; import { CoreDirectivesRegistry } from '@singletons/directives-registry'; diff --git a/src/core/components/tabs-outlet/tabs-outlet.ts b/src/core/components/tabs-outlet/tabs-outlet.ts index 65c254d61..fd9dce45d 100644 --- a/src/core/components/tabs-outlet/tabs-outlet.ts +++ b/src/core/components/tabs-outlet/tabs-outlet.ts @@ -23,7 +23,7 @@ import { } from '@angular/core'; import { IonRouterOutlet, IonTabs, ViewDidEnter, ViewDidLeave } from '@ionic/angular'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { Params } from '@angular/router'; import { CoreNavBarButtonsComponent } from '../navbar-buttons/navbar-buttons'; import { StackDidChangeEvent } from '@ionic/angular/common/directives/navigation/stack-utils'; diff --git a/src/core/components/tabs/tab.ts b/src/core/components/tabs/tab.ts index a7294e67f..b88dd6169 100644 --- a/src/core/components/tabs/tab.ts +++ b/src/core/components/tabs/tab.ts @@ -15,7 +15,7 @@ import { Component, Input, Output, OnInit, OnDestroy, ElementRef, EventEmitter, ContentChild, TemplateRef } from '@angular/core'; import { CoreTabBase } from '@classes/tabs'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { CoreDirectivesRegistry } from '@singletons/directives-registry'; import { CoreNavBarButtonsComponent } from '../navbar-buttons/navbar-buttons'; import { CoreTabsComponent } from './tabs'; diff --git a/src/core/components/user-avatar/user-avatar.ts b/src/core/components/user-avatar/user-avatar.ts index 994f94527..7cb3b866e 100644 --- a/src/core/components/user-avatar/user-avatar.ts +++ b/src/core/components/user-avatar/user-avatar.ts @@ -15,7 +15,7 @@ import { Component, Input, OnInit, OnChanges, OnDestroy, SimpleChange } from '@angular/core'; import { CoreSiteBasicInfo, CoreSites } from '@services/sites'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { CoreEventObserver, CoreEvents } from '@singletons/events'; import { USER_PROFILE_PICTURE_UPDATED, CoreUserBasicData } from '@features/user/services/user'; import { CoreNavigator } from '@services/navigator'; diff --git a/src/core/directives/collapsible-footer.ts b/src/core/directives/collapsible-footer.ts index 7c87d1450..d58f14a1d 100644 --- a/src/core/directives/collapsible-footer.ts +++ b/src/core/directives/collapsible-footer.ts @@ -15,7 +15,7 @@ import { Directive, ElementRef, Input, OnDestroy, OnInit } from '@angular/core'; import { ScrollDetail } from '@ionic/core'; import { IonContent } from '@ionic/angular'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { CoreMath } from '@singletons/math'; import { CoreDirectivesRegistry } from '@singletons/directives-registry'; import { CoreFormatTextDirective } from './format-text'; diff --git a/src/core/directives/collapsible-item.ts b/src/core/directives/collapsible-item.ts index a845e0a14..642169c3b 100644 --- a/src/core/directives/collapsible-item.ts +++ b/src/core/directives/collapsible-item.ts @@ -16,7 +16,7 @@ import { Directive, ElementRef, Input, OnDestroy, OnInit } from '@angular/core'; import { CoreCancellablePromise } from '@classes/cancellable-promise'; import { CoreLoadingComponent } from '@components/loading/loading'; import { CoreSettingsHelper } from '@features/settings/services/settings-helper'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { Translate } from '@singletons'; import { CoreColors } from '@singletons/colors'; import { CoreDirectivesRegistry } from '@singletons/directives-registry'; diff --git a/src/core/directives/on-resize.ts b/src/core/directives/on-resize.ts index 8660008f0..e12adcbf3 100644 --- a/src/core/directives/on-resize.ts +++ b/src/core/directives/on-resize.ts @@ -13,7 +13,7 @@ // limitations under the License. import { Directive, ElementRef, OnInit, Output, EventEmitter, OnDestroy } from '@angular/core'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; /** * Directive to listen for element resize events. diff --git a/src/core/features/contentlinks/services/contentlinks-delegate.ts b/src/core/features/contentlinks/services/contentlinks-delegate.ts index 7e24cc359..2b3e1a93c 100644 --- a/src/core/features/contentlinks/services/contentlinks-delegate.ts +++ b/src/core/features/contentlinks/services/contentlinks-delegate.ts @@ -16,7 +16,6 @@ import { Injectable } from '@angular/core'; import { CoreLogger } from '@singletons/logger'; import { CoreSites } from '@services/sites'; import { CoreUrl } from '@singletons/url'; -import { CoreUtils } from '@services/utils/utils'; import { makeSingleton } from '@singletons'; import { CoreText } from '@singletons/text'; import { CorePromiseUtils } from '@singletons/promise-utils'; @@ -188,7 +187,7 @@ export class CoreContentLinksDelegateService { } // Filter the site IDs using the isEnabled function. - promises.push(CoreUtils.filterEnabledSites(siteIds, isEnabledFn, checkAll).then(async (siteIds) => { + promises.push(CoreSites.filterEnabledSites(siteIds, isEnabledFn, checkAll).then(async (siteIds) => { if (!siteIds.length) { // No sites supported, no actions. return; diff --git a/src/core/features/course/classes/main-resource-component.ts b/src/core/features/course/classes/main-resource-component.ts index ae434cd44..2003c1e5b 100644 --- a/src/core/features/course/classes/main-resource-component.ts +++ b/src/core/features/course/classes/main-resource-component.ts @@ -19,7 +19,7 @@ import { CoreNetwork } from '@services/network'; import { CoreSites } from '@services/sites'; import { CoreDomUtils } from '@services/utils/dom'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { Translate } from '@singletons'; import { CoreEventObserver, CoreEvents } from '@singletons/events'; import { CoreLogger } from '@singletons/logger'; diff --git a/src/core/features/course/components/module-summary/module-summary.ts b/src/core/features/course/components/module-summary/module-summary.ts index 00353ebd5..b9a32df7e 100644 --- a/src/core/features/course/components/module-summary/module-summary.ts +++ b/src/core/features/course/components/module-summary/module-summary.ts @@ -29,7 +29,7 @@ import { CoreNavigator } from '@services/navigator'; import { CoreSites } from '@services/sites'; import { CoreDomUtils } from '@services/utils/dom'; import { CoreText } from '@singletons/text'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { ModalController, NgZone } from '@singletons'; import { CoreEventObserver, CoreEvents } from '@singletons/events'; import { Subscription } from 'rxjs'; diff --git a/src/core/features/course/pages/contents/contents.ts b/src/core/features/course/pages/contents/contents.ts index 5df61bb9e..958ecd0f1 100644 --- a/src/core/features/course/pages/contents/contents.ts +++ b/src/core/features/course/pages/contents/contents.ts @@ -16,7 +16,7 @@ import { Component, ViewChild, OnInit, OnDestroy, forwardRef, ChangeDetectorRef import { IonContent } from '@ionic/angular'; import { CoreDomUtils } from '@services/utils/dom'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { CoreCourses, CoreCourseAnyCourseData } from '@features/courses/services/courses'; import { CoreCourse, diff --git a/src/core/features/course/pages/module-preview/module-preview.ts b/src/core/features/course/pages/module-preview/module-preview.ts index 56769fafb..b310da7b4 100644 --- a/src/core/features/course/pages/module-preview/module-preview.ts +++ b/src/core/features/course/pages/module-preview/module-preview.ts @@ -21,7 +21,7 @@ import { CoreModals } from '@services/modals'; import { CoreNavigator } from '@services/navigator'; import { CoreSites } from '@services/sites'; import { CoreDomUtils } from '@services/utils/dom'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; /** * Page that displays a module preview. diff --git a/src/core/features/courses/pages/categories/categories.ts b/src/core/features/courses/pages/categories/categories.ts index fac272b42..c52e7bd2f 100644 --- a/src/core/features/courses/pages/categories/categories.ts +++ b/src/core/features/courses/pages/categories/categories.ts @@ -15,7 +15,7 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; import { CoreSites } from '@services/sites'; import { CoreDomUtils } from '@services/utils/dom'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { CoreCategoryData, CoreCourseListItem, CoreCourses } from '../../services/courses'; import { Translate } from '@singletons'; import { CoreNavigator } from '@services/navigator'; diff --git a/src/core/features/courses/services/handlers/enrol-push-click.ts b/src/core/features/courses/services/handlers/enrol-push-click.ts index c59dd189c..424fd4e28 100644 --- a/src/core/features/courses/services/handlers/enrol-push-click.ts +++ b/src/core/features/courses/services/handlers/enrol-push-click.ts @@ -20,7 +20,7 @@ import { CorePushNotificationsNotificationBasicData } from '@features/pushnotifi import { CoreLoadings } from '@services/loadings'; import { CoreNavigator } from '@services/navigator'; import { CoreDomUtils } from '@services/utils/dom'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { makeSingleton } from '@singletons'; /** diff --git a/src/core/features/courses/services/handlers/request-push-click.ts b/src/core/features/courses/services/handlers/request-push-click.ts index e531ffe1c..265cc1d80 100644 --- a/src/core/features/courses/services/handlers/request-push-click.ts +++ b/src/core/features/courses/services/handlers/request-push-click.ts @@ -20,7 +20,7 @@ import { CorePushNotificationsNotificationBasicData } from '@features/pushnotifi import { CoreNavigator } from '@services/navigator'; import { CoreSites } from '@services/sites'; import { CoreDomUtils } from '@services/utils/dom'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { makeSingleton } from '@singletons'; import { CorePath } from '@singletons/path'; import { CoreCourses } from '../courses'; diff --git a/src/core/features/editor/components/rich-text-editor/rich-text-editor.ts b/src/core/features/editor/components/rich-text-editor/rich-text-editor.ts index 97ddd2dae..516bdc18c 100644 --- a/src/core/features/editor/components/rich-text-editor/rich-text-editor.ts +++ b/src/core/features/editor/components/rich-text-editor/rich-text-editor.ts @@ -32,7 +32,7 @@ import { CoreSites } from '@services/sites'; import { CoreFilepool } from '@services/filepool'; import { CoreDomUtils } from '@services/utils/dom'; import { CoreUrl } from '@singletons/url'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { CoreEventFormActionData, CoreEventObserver, CoreEvents } from '@singletons/events'; import { CoreEditorOffline } from '../../services/editor-offline'; import { CoreDirectivesRegistry } from '@singletons/directives-registry'; diff --git a/src/core/features/enrol/services/enrol-helper.ts b/src/core/features/enrol/services/enrol-helper.ts index 72ef71821..2290141f7 100644 --- a/src/core/features/enrol/services/enrol-helper.ts +++ b/src/core/features/enrol/services/enrol-helper.ts @@ -15,7 +15,7 @@ import { Injectable } from '@angular/core'; import { makeSingleton } from '@singletons'; import { CoreEnrolAction, CoreEnrolDelegate, CoreEnrolInfoIcon } from './enrol-delegate'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { CoreEnrol, CoreEnrolEnrolmentMethod } from './enrol'; import { CoreArray } from '@singletons/array'; diff --git a/src/core/features/enrol/services/enrol.ts b/src/core/features/enrol/services/enrol.ts index a43d635ca..a552c218c 100644 --- a/src/core/features/enrol/services/enrol.ts +++ b/src/core/features/enrol/services/enrol.ts @@ -15,7 +15,7 @@ import { Injectable } from '@angular/core'; import { makeSingleton } from '@singletons'; import { CoreSites } from '@services/sites'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { CoreEnrolAction, CoreEnrolDelegate } from './enrol-delegate'; import { CoreCacheUpdateFrequency } from '@/core/constants'; diff --git a/src/core/features/fileuploader/services/fileuploader.ts b/src/core/features/fileuploader/services/fileuploader.ts index 34270f5ee..6a4add07a 100644 --- a/src/core/features/fileuploader/services/fileuploader.ts +++ b/src/core/features/fileuploader/services/fileuploader.ts @@ -24,7 +24,7 @@ import { CoreFilepool } from '@services/filepool'; import { CoreSites } from '@services/sites'; import { CoreMimetypeUtils } from '@services/utils/mimetype'; import { CoreTimeUtils } from '@services/utils/time'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { CoreWSFile, CoreWSFileUploadOptions, CoreWSUploadFileResult } from '@services/ws'; import { makeSingleton, Translate, MediaCapture, Camera } from '@singletons'; import { CoreLogger } from '@singletons/logger'; diff --git a/src/core/features/grades/services/grades-helper.ts b/src/core/features/grades/services/grades-helper.ts index 6a0afaaf2..23bc939a3 100644 --- a/src/core/features/grades/services/grades-helper.ts +++ b/src/core/features/grades/services/grades-helper.ts @@ -35,7 +35,7 @@ import { } from '@features/grades/services/grades'; import { CoreText } from '@singletons/text'; import { CoreUrl } from '@singletons/url'; -import { CoreMenuItem, CoreUtils } from '@services/utils/utils'; +import { CoreMenuItem, CoreUtils } from '@singletons/utils'; import { CoreDomUtils } from '@services/utils/dom'; import { CoreNavigator } from '@services/navigator'; import { makeSingleton, Translate } from '@singletons'; diff --git a/src/core/features/h5p/classes/content-validator.ts b/src/core/features/h5p/classes/content-validator.ts index a98734cfb..26c585429 100644 --- a/src/core/features/h5p/classes/content-validator.ts +++ b/src/core/features/h5p/classes/content-validator.ts @@ -13,7 +13,7 @@ // limitations under the License. import { CoreText } from '@singletons/text'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { CoreH5P } from '@features/h5p/services/h5p'; import { Translate } from '@singletons'; import { CoreH5PCore, CoreH5PLibraryData, CoreH5PLibraryAddonData, CoreH5PContentDepsTreeDependency } from './core'; diff --git a/src/core/features/h5p/classes/core.ts b/src/core/features/h5p/classes/core.ts index d186c14d7..fccdb027a 100644 --- a/src/core/features/h5p/classes/core.ts +++ b/src/core/features/h5p/classes/core.ts @@ -16,7 +16,7 @@ import { Md5 } from 'ts-md5/dist/md5'; import { CoreSites } from '@services/sites'; import { CoreText } from '@singletons/text'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { CoreH5P } from '@features/h5p/services/h5p'; import { CoreH5PFileStorage } from './file-storage'; import { CoreH5PFramework } from './framework'; diff --git a/src/core/features/h5p/classes/helper.ts b/src/core/features/h5p/classes/helper.ts index 6bb2f9421..375f7add3 100644 --- a/src/core/features/h5p/classes/helper.ts +++ b/src/core/features/h5p/classes/helper.ts @@ -17,7 +17,6 @@ import { FileEntry } from '@awesome-cordova-plugins/file/ngx'; import { CoreFile, CoreFileProvider } from '@services/file'; import { CoreSites } from '@services/sites'; import { CoreMimetypeUtils } from '@services/utils/mimetype'; -import { CoreUtils } from '@services/utils/utils'; import { CoreH5P } from '../services/h5p'; import { CoreH5PCore, CoreH5PDisplayOptions, CoreH5PLocalization } from './core'; import { CoreError } from '@classes/errors/error'; @@ -56,10 +55,8 @@ export class CoreH5PHelper { const config: CoreH5PDisplayOptions = { export: false, // Don't allow downloading in the app. embed: false, // Don't display the embed button in the app. - copyright: CoreUtils.notNullOrUndefined(displayOptionsObject[CoreH5PCore.DISPLAY_OPTION_COPYRIGHT]) ? - displayOptionsObject[CoreH5PCore.DISPLAY_OPTION_COPYRIGHT] : false, - icon: CoreUtils.notNullOrUndefined(displayOptionsObject[CoreH5PCore.DISPLAY_OPTION_ABOUT]) ? - displayOptionsObject[CoreH5PCore.DISPLAY_OPTION_ABOUT] : false, + copyright: displayOptionsObject[CoreH5PCore.DISPLAY_OPTION_COPYRIGHT] ?? false, + icon: displayOptionsObject[CoreH5PCore.DISPLAY_OPTION_ABOUT] ?? false, }; config.frame = config.copyright || config.export || config.embed; diff --git a/src/core/features/h5p/classes/player.ts b/src/core/features/h5p/classes/player.ts index fc104fc98..1da7d60cb 100644 --- a/src/core/features/h5p/classes/player.ts +++ b/src/core/features/h5p/classes/player.ts @@ -15,7 +15,7 @@ import { CoreFile } from '@services/file'; import { CoreSites } from '@services/sites'; import { CoreUrl } from '@singletons/url'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { CoreH5P } from '../services/h5p'; import { CoreH5PCore, CoreH5PDisplayOptions, CoreH5PContentData, CoreH5PDependenciesFiles } from './core'; import { CoreH5PCoreSettings, CoreH5PHelper } from './helper'; diff --git a/src/core/features/login/pages/site/site.ts b/src/core/features/login/pages/site/site.ts index 3cc155a6a..02d9cb4b5 100644 --- a/src/core/features/login/pages/site/site.ts +++ b/src/core/features/login/pages/site/site.ts @@ -18,7 +18,7 @@ import { FormBuilder, FormGroup, ValidatorFn, AbstractControl, ValidationErrors import { CoreNetwork } from '@services/network'; import { CoreConfig } from '@services/config'; import { CoreSites, CoreSiteCheckResponse, CoreLoginSiteInfo, CoreSitesDemoSiteData } from '@services/sites'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { CoreDomUtils } from '@services/utils/dom'; import { CoreLoginHelper, diff --git a/src/core/features/mainmenu/pages/menu/menu.ts b/src/core/features/mainmenu/pages/menu/menu.ts index 16ceee0f5..8f59e6d8f 100644 --- a/src/core/features/mainmenu/pages/menu/menu.ts +++ b/src/core/features/mainmenu/pages/menu/menu.ts @@ -21,7 +21,7 @@ import { CoreEvents, CoreEventObserver } from '@singletons/events'; import { CoreMainMenu } from '../../services/mainmenu'; import { CoreMainMenuDelegate, CoreMainMenuHandlerToDisplay } from '../../services/mainmenu-delegate'; import { Router } from '@singletons'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { CoreAriaRoleTab, CoreAriaRoleTabFindable } from '@classes/aria-role-tab'; import { CoreNavigator } from '@services/navigator'; import { filter } from 'rxjs/operators'; diff --git a/src/core/features/pushnotifications/services/pushnotifications.ts b/src/core/features/pushnotifications/services/pushnotifications.ts index 3550f9b6d..3144fbeae 100644 --- a/src/core/features/pushnotifications/services/pushnotifications.ts +++ b/src/core/features/pushnotifications/services/pushnotifications.ts @@ -20,7 +20,7 @@ import { CoreAppDB } from '@services/app-db'; import { CoreSites } from '@services/sites'; import { CorePushNotificationsDelegate } from './push-delegate'; import { CoreLocalNotifications } from '@services/local-notifications'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { CoreText } from '@singletons/text'; import { CoreConfig } from '@services/config'; import { CoreConstants } from '@/core/constants'; diff --git a/src/core/features/question/services/question-helper.ts b/src/core/features/question/services/question-helper.ts index 00eaf6f5f..0ed8aeffa 100644 --- a/src/core/features/question/services/question-helper.ts +++ b/src/core/features/question/services/question-helper.ts @@ -21,7 +21,7 @@ import { CoreFilepool } from '@services/filepool'; import { CoreSites } from '@services/sites'; import { CoreDomUtils } from '@services/utils/dom'; import { CoreText } from '@singletons/text'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { CoreWSFile } from '@services/ws'; import { makeSingleton, Translate } from '@singletons'; import { CoreQuestion, CoreQuestionProvider, CoreQuestionQuestionParsed, CoreQuestionsAnswers } from './question'; diff --git a/src/core/features/search/pages/global-search/global-search.ts b/src/core/features/search/pages/global-search/global-search.ts index 20aa928db..9e7091f8c 100644 --- a/src/core/features/search/pages/global-search/global-search.ts +++ b/src/core/features/search/pages/global-search/global-search.ts @@ -16,7 +16,7 @@ import { Component, OnInit, OnDestroy, AfterViewInit, ViewChild } from '@angular import { CoreDomUtils } from '@services/utils/dom'; import { CoreSearchGlobalSearchResultsSource } from '@features/search/classes/global-search-results-source'; import { CoreSites } from '@services/sites'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { CoreAnalytics, CoreAnalyticsEventType } from '@services/analytics'; import { Translate } from '@singletons'; import { CoreUrl } from '@singletons/url'; diff --git a/src/core/features/siteplugins/components/module-index/module-index.ts b/src/core/features/siteplugins/components/module-index/module-index.ts index 4e4daec16..4ffd03c41 100644 --- a/src/core/features/siteplugins/components/module-index/module-index.ts +++ b/src/core/features/siteplugins/components/module-index/module-index.ts @@ -29,7 +29,7 @@ import { CoreSitePluginsCourseModuleHandlerData, } from '@features/siteplugins/services/siteplugins'; import { CoreModals } from '@services/modals'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { CoreSitePluginsPluginContentComponent, CoreSitePluginsPluginContentLoadedData } from '../plugin-content/plugin-content'; import { CoreCompileHtmlComponentModule } from '@features/compile/components/compile-html/compile-html.module'; import { CoreCourseComponentsModule } from '@features/course/components/components.module'; diff --git a/src/core/features/siteplugins/pages/course-option/course-option.ts b/src/core/features/siteplugins/pages/course-option/course-option.ts index 56fd4ad73..05c4abefe 100644 --- a/src/core/features/siteplugins/pages/course-option/course-option.ts +++ b/src/core/features/siteplugins/pages/course-option/course-option.ts @@ -16,7 +16,7 @@ import { Component, OnInit, ViewChild } from '@angular/core'; import { CoreSitePluginsPluginContentComponent } from '@features/siteplugins/components/plugin-content/plugin-content'; import { CoreSitePlugins, CoreSitePluginsContent } from '@features/siteplugins/services/siteplugins'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { CoreNavigator } from '@services/navigator'; import { CoreSharedModule } from '@/core/shared.module'; diff --git a/src/core/features/siteplugins/pages/plugin/plugin.ts b/src/core/features/siteplugins/pages/plugin/plugin.ts index e7497ff7f..297965ac3 100644 --- a/src/core/features/siteplugins/pages/plugin/plugin.ts +++ b/src/core/features/siteplugins/pages/plugin/plugin.ts @@ -17,7 +17,7 @@ import { CoreSiteWSPreSets } from '@classes/sites/authenticated-site'; import { CoreSitePluginsContent } from '@features/siteplugins/services/siteplugins'; import { CanLeave } from '@guards/can-leave'; import { CoreNavigator } from '@services/navigator'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { CoreSitePluginsPluginContentComponent } from '../../components/plugin-content/plugin-content'; import { CoreSharedModule } from '@/core/shared.module'; diff --git a/src/core/features/siteplugins/services/siteplugins.ts b/src/core/features/siteplugins/services/siteplugins.ts index 63b1d3e30..73c7f77bb 100644 --- a/src/core/features/siteplugins/services/siteplugins.ts +++ b/src/core/features/siteplugins/services/siteplugins.ts @@ -22,7 +22,7 @@ import { CoreFilepool } from '@services/filepool'; import { CoreLang, CoreLangFormat } from '@services/lang'; import { CoreSites } from '@services/sites'; import { CoreText } from '@singletons/text'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { CoreWSExternalFile, CoreWSExternalWarning } from '@services/ws'; import { makeSingleton } from '@singletons'; import { CoreEvents } from '@singletons/events'; diff --git a/src/core/features/user/components/user-profile-field/user-profile-field.ts b/src/core/features/user/components/user-profile-field/user-profile-field.ts index 9a33ee6ed..bfbdae44b 100644 --- a/src/core/features/user/components/user-profile-field/user-profile-field.ts +++ b/src/core/features/user/components/user-profile-field/user-profile-field.ts @@ -18,7 +18,7 @@ import { CoreLang } from '@services/lang'; import { AuthEmailSignupProfileField } from '@features/login/services/login-helper'; import { CoreUserProfileField } from '@features/user/services/user'; import { CoreUserProfileFieldDelegate } from '@features/user/services/user-profile-field-delegate'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { ContextLevel } from '@/core/constants'; import { toBoolean } from '@/core/transforms/boolean'; diff --git a/src/core/services/navigator.ts b/src/core/services/navigator.ts index e86ae2ec1..096aa1956 100644 --- a/src/core/services/navigator.ts +++ b/src/core/services/navigator.ts @@ -21,7 +21,7 @@ import { CoreConstants } from '@/core/constants'; import { CoreMainMenu } from '@features/mainmenu/services/mainmenu'; import { CoreObject } from '@singletons/object'; import { CoreSites } from '@services/sites'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { CoreUrl, CoreUrlPartNames } from '@singletons/url'; import { CoreText } from '@singletons/text'; import { makeSingleton, NavController, Router } from '@singletons'; diff --git a/src/core/services/sites.ts b/src/core/services/sites.ts index be8ef72f1..b402491b3 100644 --- a/src/core/services/sites.ts +++ b/src/core/services/sites.ts @@ -21,7 +21,6 @@ import { CoreEvents } from '@singletons/events'; import { CoreWS } from '@services/ws'; import { CoreDomUtils } from '@services/utils/dom'; import { CoreUrl, CoreUrlPartNames } from '@singletons/url'; -import { CoreUtils } from '@services/utils/utils'; import { CoreConstants, MINIMUM_MOODLE_VERSION, MOODLE_RELEASES } from '@/core/constants'; import { CoreSite, @@ -466,7 +465,7 @@ export class CoreSitesProvider { if (error.debug?.code === 'codingerror') { // This could be caused by a redirect. Check if it's the case. - const redirect = await CoreUtils.checkRedirect(siteUrl); + const redirect = await CoreRedirects.checkRedirect(siteUrl); options.message = Translate.instant('core.siteunavailablehelp', { site: siteUrl }); @@ -557,9 +556,9 @@ export class CoreSitesProvider { return this.getUserToken(siteUrl, username, password, service, true); } - if (data.errorcode == 'missingparam') { + if (data.errorcode === 'missingparam') { // It seems the server didn't receive all required params, it could be due to a redirect. - const redirect = await CoreUtils.checkRedirect(loginUrl); + const redirect = await CoreRedirects.checkRedirect(loginUrl); if (redirect) { throw this.createCannotConnectLoginError(siteUrl, { @@ -2217,6 +2216,47 @@ export class CoreSitesProvider { this.afterLoginNavigationQueue = []; } + /** + * Filter the list of site IDs based on a isEnabled function. + * + * @param siteIds Site IDs to filter. + * @param isEnabledFn Function to call for each site. It receives a siteId param and all the params sent to this function + * after 'checkAll'. + * @param checkAll True if it should check all the sites, false if it should check only 1 and treat them all + * depending on this result. + * @returns Promise resolved with the list of enabled sites. + */ + async filterEnabledSites

( + siteIds: string[], + isEnabledFn: (siteId: string, ...args: P) => boolean | Promise, + checkAll?: boolean, + ...args: P + ): Promise { + const promises: Promise[] = []; + const enabledSites: string[] = []; + + for (const i in siteIds) { + const siteId = siteIds[i]; + const pushIfEnabled = enabled => enabled && enabledSites.push(siteId); + if (checkAll || !promises.length) { + promises.push( + Promise + .resolve(isEnabledFn(siteId, ...args)) + .then(pushIfEnabled), + ); + } + } + + await CorePromiseUtils.allPromisesIgnoringErrors(promises); + + if (!checkAll) { + // Checking 1 was enough, so it will either return all the sites or none. + return enabledSites.length ? siteIds : []; + } + + return enabledSites; + } + } export const CoreSites = makeSingleton(CoreSitesProvider); diff --git a/src/core/services/utils/utils.ts b/src/core/services/utils/utils.ts index 8fe25b9a2..df4ca3209 100644 --- a/src/core/services/utils/utils.ts +++ b/src/core/services/utils/utils.ts @@ -16,10 +16,9 @@ import { Injectable } from '@angular/core'; import { InAppBrowserObject } from '@awesome-cordova-plugins/in-app-browser'; import { FileEntry } from '@awesome-cordova-plugins/file/ngx'; import { CoreFileUtils } from '@singletons/file-utils'; -import { CoreWS } from '@services/ws'; +import { CoreRedirects } from '@singletons/redirects'; import { CoreMimetypeUtils } from '@services/utils/mimetype'; -import { makeSingleton, Translate } from '@singletons'; -import { CoreLogger } from '@singletons/logger'; +import { makeSingleton } from '@singletons'; import { CoreFileEntry } from '@services/file-helper'; import { CoreCancellablePromise } from '@classes/cancellable-promise'; import { CoreArray } from '@singletons/array'; @@ -31,8 +30,9 @@ import { CorePromiseUtils, OrderedPromiseData } from '@singletons/promise-utils' import { CoreOpener, CoreOpenerOpenFileOptions, CoreOpenerOpenInBrowserOptions } from '@singletons/opener'; import { CoreCountries, CoreCountry } from '@singletons/countries'; import { CoreObject } from '@singletons/object'; - -export type TreeNode = T & { children: TreeNode[] }; +import { CoreSites } from '@services/sites'; +import { CoreMenuItem, CoreUtils as CoreUtilsSingleton, TreeNode } from '@singletons/utils'; +import { CoreWSError } from '@classes/errors/wserror'; /* * "Utils" service with helper functions. @@ -40,15 +40,6 @@ export type TreeNode = T & { children: TreeNode[] }; @Injectable({ providedIn: 'root' }) export class CoreUtilsProvider { - protected readonly DONT_CLONE = ['[object FileEntry]', '[object DirectoryEntry]', '[object DOMFileSystem]']; - - protected logger: CoreLogger; - protected uniqueIds: {[name: string]: number} = {}; - - constructor() { - this.logger = CoreLogger.getInstance('CoreUtilsProvider'); - } - /** * Given an error, add an extra warning to the error message and return the new error message. * @@ -158,35 +149,10 @@ export class CoreUtilsProvider { * * @param url The URL to check. * @returns Promise resolved with boolean_ whether there is a redirect. + * @deprecated since 5.0. Use CoreRedirects.checkRedirect instead. */ async checkRedirect(url: string): Promise { - if (!window.fetch) { - // Cannot check if there is a redirect, assume it's false. - return false; - } - - const initOptions: RequestInit = { redirect: 'follow' }; - - // Some browsers implement fetch but no AbortController. - const controller = AbortController ? new AbortController() : false; - - if (controller) { - initOptions.signal = controller.signal; - } - - try { - const response = await CorePromiseUtils.timeoutPromise(window.fetch(url, initOptions), CoreWS.getRequestTimeout()); - - return response.redirected; - } catch (error) { - if (error.timeout && controller) { - // Timeout, abort the request. - controller.abort(); - } - - // There was a timeout, cannot determine if there's a redirect. Assume it's false. - return false; - } + return CoreRedirects.checkRedirect(url); } /** @@ -224,44 +190,10 @@ export class CoreUtilsProvider { * @param source The variable to clone. * @param level Depth we are right now inside a cloned object. It's used to prevent reaching max call stack size. * @returns Cloned variable. + * @deprecated since 5.0. Use CoreUtils.clone instead. */ clone(source: T, level: number = 0): T { - if (level >= 20) { - // Max 20 levels. - this.logger.error('Max depth reached when cloning object.', source); - - return source; - } - - if (CoreFileUtils.valueIsFileEntry(source)) { - // Don't clone FileEntry. It has a lot of depth and they shouldn't be modified. - return source; - } else if (Array.isArray(source)) { - // Clone the array and all the entries. - const newArray = [] as unknown as T; - for (let i = 0; i < source.length; i++) { - newArray[i] = this.clone(source[i], level + 1); - } - - return newArray; - } else if (CoreObject.isObject(source)) { - // Check if the object shouldn't be copied. - if (source.toString && this.DONT_CLONE.indexOf(source.toString()) != -1) { - // Object shouldn't be copied, return it as it is. - return source; - } - - // Clone the object and all the subproperties. - const newObject = {} as T; - for (const name in source) { - newObject[name] = this.clone(source[name], level + 1); - } - - return newObject; - } else { - // Primitive type or unknown, return it as it is. - return source; - } + return CoreUtilsSingleton.clone(source, level); } /** @@ -275,7 +207,7 @@ export class CoreUtilsProvider { copyProperties(from: Record, to: Record, clone: boolean = true): void { for (const name in from) { if (clone) { - to[name] = this.clone(from[name]); + to[name] = CoreUtilsSingleton.clone(from[name]); } else { to[name] = from[name]; } @@ -363,6 +295,7 @@ export class CoreUtilsProvider { * @param checkAll True if it should check all the sites, false if it should check only 1 and treat them all * depending on this result. * @returns Promise resolved with the list of enabled sites. + * @deprecated since 5.0. Use CoreSites.filterEnabledSites instead. */ async filterEnabledSites

( siteIds: string[], @@ -370,29 +303,7 @@ export class CoreUtilsProvider { checkAll?: boolean, ...args: P ): Promise { - const promises: Promise[] = []; - const enabledSites: string[] = []; - - for (const i in siteIds) { - const siteId = siteIds[i]; - const pushIfEnabled = enabled => enabled && enabledSites.push(siteId); - if (checkAll || !promises.length) { - promises.push( - Promise - .resolve(isEnabledFn(siteId, ...args)) - .then(pushIfEnabled), - ); - } - } - - await CorePromiseUtils.allPromisesIgnoringErrors(promises); - - if (!checkAll) { - // Checking 1 was enough, so it will either return all the sites or none. - return enabledSites.length ? siteIds : []; - } else { - return enabledSites; - } + return CoreSites.filterEnabledSites(siteIds, isEnabledFn, checkAll, ...args); } /** @@ -401,17 +312,10 @@ export class CoreUtilsProvider { * * @param float The float to print. * @returns Locale float. + * @deprecated since 5.0. Use CoreUtils.formatFloat on singletons instead. */ formatFloat(float: unknown): string { - if (float === undefined || float === null || typeof float == 'boolean') { - return ''; - } - - const localeSeparator = Translate.instant('core.decsep'); - - const floatString = String(float); - - return floatString.replace('.', localeSeparator); + return CoreUtilsSingleton.formatFloat(float); } /** @@ -425,6 +329,7 @@ export class CoreUtilsProvider { * @param rootParentId The id of the root. * @param maxDepth Max Depth to convert to tree. Children found will be in the last level of depth. * @returns Array with the formatted tree, children will be on each node under children field. + * @deprecated since 5.0. Use CoreUtils.formatTree on singletons instead. */ formatTree( list: T[], @@ -433,67 +338,7 @@ export class CoreUtilsProvider { rootParentId: number = 0, maxDepth: number = 5, ): TreeNode[] { - const map = {}; - const mapDepth = {}; - const tree: TreeNode[] = []; - - // Create a map first to avoid problems with not sorted. - list.forEach((node: TreeNode, index): void => { - const id = node[idFieldName]; - - if (id === undefined) { - this.logger.error(`Node with incorrect ${idFieldName}:${id} found on formatTree`); - } - - if (node.children === undefined) { - node.children = []; - } - map[id] = index; - }); - - list.forEach((node: TreeNode): void => { - const id = node[idFieldName]; - const parent = node[parentFieldName]; - - if (id === undefined || parent === undefined) { - this.logger.error(`Node with incorrect ${idFieldName}:${id} or ${parentFieldName}:${parent} found on formatTree`); - } - - // Use map to look-up the parents. - if (parent !== rootParentId) { - const parentNode = list[map[parent]] as TreeNode; - if (parentNode) { - if (mapDepth[parent] == maxDepth) { - // Reached max level of depth. Proceed with flat order. Find parent object of the current node. - const parentOfParent = parentNode[parentFieldName]; - if (parentOfParent) { - // This element will be the child of the node that is two levels up the hierarchy - // (i.e. the child of node.parent.parent). - (list[map[parentOfParent]] as TreeNode).children.push(node); - // Assign depth level to the same depth as the parent (i.e. max depth level). - mapDepth[id] = mapDepth[parent]; - // Change the parent to be the one that is two levels up the hierarchy. - node[parentFieldName] = parentOfParent; - } else { - this.logger.error(`Node parent of parent:${parentOfParent} not found on formatTree`); - } - } else { - parentNode.children.push(node); - // Increase the depth level. - mapDepth[id] = mapDepth[parent] + 1; - } - } else { - this.logger.error(`Node parent:${parent} not found on formatTree`); - } - } else { - tree.push(node); - - // Root elements are the first elements in the tree structure, therefore have the depth level 1. - mapDepth[id] = 1; - } - }); - - return tree; + return CoreUtilsSingleton.formatTree(list, parentFieldName, idFieldName, rootParentId, maxDepth); } /** @@ -545,13 +390,10 @@ export class CoreUtilsProvider { * * @param name The name to get the ID for. * @returns Unique ID. + * @deprecated since 5.0. Use CoreUtils.getUniqueId singleton instead. */ getUniqueId(name: string): number { - if (!this.uniqueIds[name]) { - this.uniqueIds[name] = 0; - } - - return ++this.uniqueIds[name]; + return CoreUtilsSingleton.getUniqueId(name); } /** @@ -615,10 +457,11 @@ export class CoreUtilsProvider { * * @param value Value to check. * @returns Whether the value is false, 0 or "0". + * @deprecated since 5.0. Use CoreUtils.isFalseOrZero singleton instead. */ // eslint-disable-next-line @typescript-eslint/no-explicit-any isFalseOrZero(value: any): boolean { - return value !== undefined && (value === false || value === 'false' || parseInt(value, 10) === 0); + return CoreUtilsSingleton.isFalseOrZero(value); } /** @@ -626,10 +469,11 @@ export class CoreUtilsProvider { * * @param value Value to check. * @returns Whether the value is true, 1 or "1". + * @deprecated since 5.0. Use CoreUtils.isTrueOrOne singleton instead. */ // eslint-disable-next-line @typescript-eslint/no-explicit-any isTrueOrOne(value: any): boolean { - return value !== undefined && (value === true || value === 'true' || parseInt(value, 10) === 1); + return CoreUtilsSingleton.isTrueOrOne(value); } /** @@ -641,18 +485,7 @@ export class CoreUtilsProvider { */ // eslint-disable-next-line @typescript-eslint/no-explicit-any isWebServiceError(error: any): boolean { - return error && ( - error.warningcode !== undefined || - ( - error.errorcode !== undefined && error.errorcode != 'userdeleted' && error.errorcode != 'upgraderunning' && - error.errorcode != 'forcepasswordchangenotice' && error.errorcode != 'usernotfullysetup' && - error.errorcode != 'sitepolicynotagreed' && error.errorcode != 'sitemaintenance' && - error.errorcode != 'wsaccessusersuspended' && error.errorcode != 'wsaccessuserdeleted' && - // eslint-disable-next-line deprecation/deprecation - !this.isExpiredTokenError(error) - ) || - error.status && error.status >= 400 // CoreHttpError, assume status 400 and above are like WebService errors. - ); + return CoreWSError.isWebServiceError(error); } /** @@ -664,8 +497,7 @@ export class CoreUtilsProvider { */ // eslint-disable-next-line @typescript-eslint/no-explicit-any isExpiredTokenError(error: any): boolean { - return error.errorcode === 'invalidtoken' || - (error.errorcode === 'accessexception' && error.message.includes('Invalid token - token expired')); + return CoreWSError.isExpiredTokenError(error); } /** @@ -677,6 +509,7 @@ export class CoreUtilsProvider { * @param separator The separator used within the list string. Default ','. * @param defaultValue Element that will become default option value. Default 0. * @returns The now assembled array + * @deprecated since 5.0. Use CoreUtils.makeMenuFromList singleton instead. */ makeMenuFromList( list: string, @@ -684,20 +517,7 @@ export class CoreUtilsProvider { separator: string = ',', defaultValue?: T, ): CoreMenuItem[] { - // Split and format the list. - const split = list.split(separator).map((label, index) => ({ - label: label.trim(), - value: index + 1, - })) as { label: string; value: T | number }[]; - - if (defaultLabel) { - split.unshift({ - label: defaultLabel, - value: defaultValue || 0, - }); - } - - return split; + return CoreUtilsSingleton.makeMenuFromList(list, defaultLabel, separator, defaultValue); } /** @@ -718,6 +538,7 @@ export class CoreUtilsProvider { * * @param value Value to check. * @returns True if not null and not undefined. + * @deprecated since 5.0. Use ?? instead. */ // eslint-disable-next-line @typescript-eslint/no-explicit-any notNullOrUndefined(value: any): boolean { @@ -967,39 +788,10 @@ export class CoreUtilsProvider { * @param localeFloat Locale aware float representation. * @param strict If true, then check the input and return false if it is not a valid number. * @returns False if bad format, empty string if empty value or the parsed float if not. + * @deprecated since 5.0. Use CoreUtils.unformatFloat on singletons instead. */ unformatFloat(localeFloat: string | number | null | undefined, strict?: boolean): false | '' | number { - // Bad format on input type number. - if (localeFloat === undefined) { - return false; - } - - // Empty (but not zero). - if (localeFloat == null) { - return ''; - } - - // Convert float to string. - localeFloat = String(localeFloat); - localeFloat = localeFloat.trim(); - - if (localeFloat == '') { - return ''; - } - - localeFloat = localeFloat.replace(' ', ''); // No spaces - those might be used as thousand separators. - localeFloat = localeFloat.replace(Translate.instant('core.decsep'), '.'); - - // Use Number instead of parseFloat because the latter truncates the number when it finds ",", while Number returns NaN. - // If the number still has "," then it means it's not a valid separator. - const parsedFloat = Number(localeFloat); - - // Bad format. - if (strict && (!isFinite(parsedFloat) || isNaN(parsedFloat))) { - return false; - } - - return parsedFloat; + return CoreUtilsSingleton.unformatFloat(localeFloat, strict); } /** @@ -1020,17 +812,10 @@ export class CoreUtilsProvider { * @param fn Function to debounce. * @param delay Time that must pass until the function is called. * @returns Debounced function. + * @deprecated since 5.0. Use CoreUtils.debounce on singletons instead. */ debounce(fn: (...args: T) => unknown, delay: number): (...args: T) => void { - let timeoutID: number; - - const debounced = (...args: T): void => { - clearTimeout(timeoutID); - - timeoutID = window.setTimeout(() => fn.apply(null, args), delay); - }; - - return debounced; + return CoreUtilsSingleton.debounce(fn, delay); } /** @@ -1039,23 +824,10 @@ export class CoreUtilsProvider { * @param fn Function to throttle. * @param duration Time that must pass until the function is called. * @returns Throttled function. + * @deprecated since 5.0. Use CoreUtils.throttle on singletons instead. */ throttle(fn: (...args: T) => unknown, duration: number): (...args: T) => void { - let shouldWait = false; - - const throttled = (...args: T): void => { - if (!shouldWait) { - fn.apply(null, args); - - shouldWait = true; - - setTimeout(() => { - shouldWait = false; - }, duration); - } - }; - - return throttled; + return CoreUtilsSingleton.throttle(fn, duration); } /** @@ -1182,14 +954,6 @@ export class CoreUtilsProvider { export const CoreUtils = makeSingleton(CoreUtilsProvider); -/** - * Menu item. - */ -export type CoreMenuItem = { - label: string; - value: T | number; -}; - /** * Options for waiting. * diff --git a/src/core/singletons/dom.ts b/src/core/singletons/dom.ts index c35b87ed6..34a671a62 100644 --- a/src/core/singletons/dom.ts +++ b/src/core/singletons/dom.ts @@ -13,7 +13,7 @@ // limitations under the License. import { CoreCancellablePromise } from '@classes/cancellable-promise'; -import { CoreUtils } from '@services/utils/utils'; +import { CoreUtils } from '@singletons/utils'; import { CoreEventObserver } from '@singletons/events'; import { CorePlatform } from '@services/platform'; import { CoreWait } from './wait'; diff --git a/src/core/singletons/redirects.ts b/src/core/singletons/redirects.ts index f0e5f0a57..befe03ac2 100644 --- a/src/core/singletons/redirects.ts +++ b/src/core/singletons/redirects.ts @@ -15,6 +15,8 @@ import { CoreRedirectPayload } from '@services/navigator'; import { CoreLogger } from './logger'; import { CoreObject } from './object'; +import { CoreWS } from '@services/ws'; +import { CorePromiseUtils } from './promise-utils'; /** * Singleton with helper functions to manage redirects. @@ -119,6 +121,42 @@ export class CoreRedirects { } } + /** + * Check if a URL has a redirect. + * + * @param url The URL to check. + * @returns Promise resolved with boolean_ whether there is a redirect. + */ + static async checkRedirect(url: string): Promise { + if (!window.fetch) { + // Cannot check if there is a redirect, assume it's false. + return false; + } + + const initOptions: RequestInit = { redirect: 'follow' }; + + // Some browsers implement fetch but no AbortController. + const controller = AbortController ? new AbortController() : false; + + if (controller) { + initOptions.signal = controller.signal; + } + + try { + const response = await CorePromiseUtils.timeoutPromise(window.fetch(url, initOptions), CoreWS.getRequestTimeout()); + + return response.redirected; + } catch (error) { + if (error.timeout && controller) { + // Timeout, abort the request. + controller.abort(); + } + + // There was a timeout, cannot determine if there's a redirect. Assume it's false. + return false; + } + } + } /** diff --git a/src/core/singletons/utils.ts b/src/core/singletons/utils.ts new file mode 100644 index 000000000..6b1a17111 --- /dev/null +++ b/src/core/singletons/utils.ts @@ -0,0 +1,348 @@ +// (C) Copyright 2015 Moodle Pty Ltd. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import { Translate } from '@singletons'; +import { CoreLogger } from './logger'; +import { CoreObject } from './object'; +import { CoreFileUtils } from './file-utils'; + +/** + * Singleton with utils helper functions. + */ +export class CoreUtils { + + // Avoid creating singleton instances. + private constructor() { + // Nothing to do. + } + + protected static readonly DONT_CLONE = ['[object FileEntry]', '[object DirectoryEntry]', '[object DOMFileSystem]']; + + protected static logger = CoreLogger.getInstance('CoreUtils'); + protected static uniqueIds: {[name: string]: number} = {}; + + /** + * Clone a variable. It should be an object, array or primitive type. + * + * @param source The variable to clone. + * @param level Depth we are right now inside a cloned object. It's used to prevent reaching max call stack size. + * @returns Cloned variable. + */ + static clone(source: T, level: number = 0): T { + if (level >= 20) { + // Max 20 levels. + CoreUtils.logger.error('Max depth reached when cloning object.', source); + + return source; + } + + if (CoreFileUtils.valueIsFileEntry(source)) { + // Don't clone FileEntry. It has a lot of depth and they shouldn't be modified. + return source; + } else if (Array.isArray(source)) { + // Clone the array and all the entries. + const newArray = [] as unknown as T; + for (let i = 0; i < source.length; i++) { + newArray[i] = CoreUtils.clone(source[i], level + 1); + } + + return newArray; + } else if (CoreObject.isObject(source)) { + // Check if the object shouldn't be copied. + if (source.toString && CoreUtils.DONT_CLONE.indexOf(source.toString()) != -1) { + // Object shouldn't be copied, return it as it is. + return source; + } + + // Clone the object and all the subproperties. + const newObject = {} as T; + for (const name in source) { + newObject[name] = CoreUtils.clone(source[name], level + 1); + } + + return newObject; + } else { + // Primitive type or unknown, return it as it is. + return source; + } + } + + /** + * Given a float, prints it nicely. Localized floats must not be used in calculations! + * Based on Moodle's format_float. + * + * @param float The float to print. + * @returns Locale float. + */ + static formatFloat(float: unknown): string { + if (float === undefined || float === null || typeof float == 'boolean') { + return ''; + } + + const localeSeparator = Translate.instant('core.decsep'); + + const floatString = String(float); + + return floatString.replace('.', localeSeparator); + } + + /** + * Returns a tree formatted from a plain list. + * List has to be sorted by depth to allow this function to work correctly. Errors can be thrown if a child node is + * processed before a parent node. + * + * @param list List to format. + * @param parentFieldName Name of the parent field to match with children. + * @param idFieldName Name of the children field to match with parent. + * @param rootParentId The id of the root. + * @param maxDepth Max Depth to convert to tree. Children found will be in the last level of depth. + * @returns Array with the formatted tree, children will be on each node under children field. + */ + static formatTree( + list: T[], + parentFieldName: string = 'parent', + idFieldName: string = 'id', + rootParentId: number = 0, + maxDepth: number = 5, + ): TreeNode[] { + const map = {}; + const mapDepth = {}; + const tree: TreeNode[] = []; + + // Create a map first to avoid problems with not sorted. + list.forEach((node: TreeNode, index): void => { + const id = node[idFieldName]; + + if (id === undefined) { + CoreUtils.logger.error(`Node with incorrect ${idFieldName}:${id} found on formatTree`); + } + + if (node.children === undefined) { + node.children = []; + } + map[id] = index; + }); + + list.forEach((node: TreeNode): void => { + const id = node[idFieldName]; + const parent = node[parentFieldName]; + + if (id === undefined || parent === undefined) { + CoreUtils.logger.error(`Node with incorrect ${idFieldName}:${id} + or ${parentFieldName}:${parent} found on formatTree`); + } + + // Use map to look-up the parents. + if (parent !== rootParentId) { + const parentNode = list[map[parent]] as TreeNode; + if (parentNode) { + if (mapDepth[parent] == maxDepth) { + // Reached max level of depth. Proceed with flat order. Find parent object of the current node. + const parentOfParent = parentNode[parentFieldName]; + if (parentOfParent) { + // This element will be the child of the node that is two levels up the hierarchy + // (i.e. the child of node.parent.parent). + (list[map[parentOfParent]] as TreeNode).children.push(node); + // Assign depth level to the same depth as the parent (i.e. max depth level). + mapDepth[id] = mapDepth[parent]; + // Change the parent to be the one that is two levels up the hierarchy. + node[parentFieldName] = parentOfParent; + } else { + CoreUtils.logger.error(`Node parent of parent:${parentOfParent} not found on formatTree`); + } + } else { + parentNode.children.push(node); + // Increase the depth level. + mapDepth[id] = mapDepth[parent] + 1; + } + } else { + CoreUtils.logger.error(`Node parent:${parent} not found on formatTree`); + } + } else { + tree.push(node); + + // Root elements are the first elements in the tree structure, therefore have the depth level 1. + mapDepth[id] = 1; + } + }); + + return tree; + } + + /** + * Get a unique ID for a certain name. + * + * @param name The name to get the ID for. + * @returns Unique ID. + */ + static getUniqueId(name: string): number { + if (!CoreUtils.uniqueIds[name]) { + CoreUtils.uniqueIds[name] = 0; + } + + return ++CoreUtils.uniqueIds[name]; + } + + /** + * Return true if the param is false (bool), 0 (number) or "0" (string). + * + * @param value Value to check. + * @returns Whether the value is false, 0 or "0". + */ + // eslint-disable-next-line @typescript-eslint/no-explicit-any + static isFalseOrZero(value: any): boolean { + return value !== undefined && (value === false || value === 'false' || parseInt(value, 10) === 0); + } + + /** + * Return true if the param is true (bool), 1 (number) or "1" (string). + * + * @param value Value to check. + * @returns Whether the value is true, 1 or "1". + */ + // eslint-disable-next-line @typescript-eslint/no-explicit-any + static isTrueOrOne(value: any): boolean { + return value !== undefined && (value === true || value === 'true' || parseInt(value, 10) === 1); + } + + /** + * Given a list (e.g. a,b,c,d,e) this function returns an array of 1->a, 2->b, 3->c etc. + * Taken from make_menu_from_list on moodlelib.php (not the same but similar). + * + * @param list The string to explode into array bits + * @param defaultLabel Element that will become default option, if not defined, it won't be added. + * @param separator The separator used within the list string. Default ','. + * @param defaultValue Element that will become default option value. Default 0. + * @returns The now assembled array + */ + static makeMenuFromList( + list: string, + defaultLabel?: string, + separator: string = ',', + defaultValue?: T, + ): CoreMenuItem[] { + // Split and format the list. + const split = list.split(separator).map((label, index) => ({ + label: label.trim(), + value: index + 1, + })) as { label: string; value: T | number }[]; + + if (defaultLabel) { + split.unshift({ + label: defaultLabel, + value: defaultValue || 0, + }); + } + + return split; + } + + /** + * Converts locale specific floating point/comma number back to a standard float number. + * Do NOT try to do any math operations before this conversion on any user submitted floats! + * Based on Moodle's unformat_float function. + * + * @param localeFloat Locale aware float representation. + * @param strict If true, then check the input and return false if it is not a valid number. + * @returns False if bad format, empty string if empty value or the parsed float if not. + */ + static unformatFloat(localeFloat: string | number | null | undefined, strict?: boolean): false | '' | number { + // Bad format on input type number. + if (localeFloat === undefined) { + return false; + } + + // Empty (but not zero). + if (localeFloat == null) { + return ''; + } + + // Convert float to string. + localeFloat = String(localeFloat); + localeFloat = localeFloat.trim(); + + if (localeFloat == '') { + return ''; + } + + localeFloat = localeFloat.replace(' ', ''); // No spaces - those might be used as thousand separators. + localeFloat = localeFloat.replace(Translate.instant('core.decsep'), '.'); + + // Use Number instead of parseFloat because the latter truncates the number when it finds ",", while Number returns NaN. + // If the number still has "," then it means it's not a valid separator. + const parsedFloat = Number(localeFloat); + + // Bad format. + if (strict && (!isFinite(parsedFloat) || isNaN(parsedFloat))) { + return false; + } + + return parsedFloat; + } + + /** + * Debounce a function so consecutive calls are ignored until a certain time has passed since the last call. + * + * @param fn Function to debounce. + * @param delay Time that must pass until the function is called. + * @returns Debounced function. + */ + static debounce(fn: (...args: T) => unknown, delay: number): (...args: T) => void { + let timeoutID: number; + + const debounced = (...args: T): void => { + clearTimeout(timeoutID); + + timeoutID = window.setTimeout(() => fn.apply(null, args), delay); + }; + + return debounced; + } + + /** + * Throttle a function so consecutive calls are ignored until a certain time has passed since the last executed call. + * + * @param fn Function to throttle. + * @param duration Time that must pass until the function is called. + * @returns Throttled function. + */ + static throttle(fn: (...args: T) => unknown, duration: number): (...args: T) => void { + let shouldWait = false; + + const throttled = (...args: T): void => { + if (!shouldWait) { + fn.apply(null, args); + + shouldWait = true; + + setTimeout(() => { + shouldWait = false; + }, duration); + } + }; + + return throttled; + } + + } + +export type TreeNode = T & { children: TreeNode[] }; + +/** + * Menu item. + */ +export type CoreMenuItem = { + label: string; + value: T | number; +}; diff --git a/src/types/config.d.ts b/src/types/config.d.ts index e3de69599..569bfaa40 100644 --- a/src/types/config.d.ts +++ b/src/types/config.d.ts @@ -15,7 +15,7 @@ import { CoreColorScheme, CoreZoomLevel } from '@features/settings/services/settings-helper'; import { CoreMainMenuLocalizedCustomItem } from '@features/mainmenu/services/mainmenu'; import { CoreLoginSiteInfo, CoreSitesDemoSiteData } from '@services/sites'; -import { OpenFileAction } from '@services/utils/utils'; +import { OpenFileAction } from '@singletons/opener'; import { CoreLoginSiteFinderSettings, CoreLoginSiteSelectorListMethod } from '@features/login/services/login-helper'; import { CoreDatabaseConfiguration } from '@classes/database/database-table'; import { ToastDuration } from '@services/toasts';