From 7cf5d9b692fe5160a1ea9d9d1ee47ce55c68f526 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Thu, 18 Jul 2024 12:35:58 +0200 Subject: [PATCH] MOBILE-4616 chore: Create CorePopoversService to add popovers functions --- src/addons/blog/pages/index/index.ts | 3 +- .../calendar/pages/edit-event/edit-event.ts | 3 +- src/addons/calendar/pages/event/event.ts | 3 +- .../calendar/pages/settings/settings.ts | 4 +- .../mod/data/components/action/action.ts | 4 +- .../mod/forum/components/index/index.ts | 3 +- src/addons/mod/forum/components/post/post.ts | 3 +- .../mod/glossary/components/index/index.ts | 3 +- src/addons/mod/quiz/classes/auto-save.ts | 4 +- src/addons/mod/wiki/components/index/index.ts | 3 +- .../components/context-menu/context-menu.ts | 4 +- src/core/core.module.ts | 2 + .../module-completion/module-completion.ts | 4 +- .../course-list-item/course-list-item.ts | 3 +- .../components/set-button/set-button.ts | 4 +- .../set-reminder-menu/set-reminder-menu.ts | 4 +- src/core/services/popovers.ts | 66 +++++++++++++++++++ src/core/services/utils/dom.ts | 32 +++------ 18 files changed, 106 insertions(+), 46 deletions(-) create mode 100644 src/core/services/popovers.ts diff --git a/src/addons/blog/pages/index/index.ts b/src/addons/blog/pages/index/index.ts index 430e425b6..d16a10e82 100644 --- a/src/addons/blog/pages/index/index.ts +++ b/src/addons/blog/pages/index/index.ts @@ -31,6 +31,7 @@ import { CoreUtils } from '@services/utils/utils'; import { CoreArray } from '@singletons/array'; import { CoreEventObserver, CoreEvents } from '@singletons/events'; import { CoreTime } from '@singletons/time'; +import { CorePopovers } from '@services/popovers'; /** * Page that displays the list of blog entries. @@ -327,7 +328,7 @@ export class AddonBlogIndexPage implements OnInit, OnDestroy { event.preventDefault(); event.stopPropagation(); - const popoverData = await CoreDomUtils.openPopover({ + const popoverData = await CorePopovers.open({ component: AddonBlogEntryOptionsMenuComponent, event, }); diff --git a/src/addons/calendar/pages/edit-event/edit-event.ts b/src/addons/calendar/pages/edit-event/edit-event.ts index fee6ccb9f..0e140ca86 100644 --- a/src/addons/calendar/pages/edit-event/edit-event.ts +++ b/src/addons/calendar/pages/edit-event/edit-event.ts @@ -47,6 +47,7 @@ import { CoreRemindersSetReminderMenuComponent } from '@features/reminders/compo import moment from 'moment-timezone'; import { ADDON_CALENDAR_COMPONENT } from '@addons/calendar/constants'; import { ContextLevel } from '@/core/constants'; +import { CorePopovers } from '@services/popovers'; /** * Page that displays a form to create/edit an event. @@ -637,7 +638,7 @@ export class AddonCalendarEditEventPage implements OnInit, OnDestroy, CanLeave { const formData = this.form.value; const eventTime = moment(formData.timestart).unix(); - const reminderTime = await CoreDomUtils.openPopover<{timeBefore: number}>({ + const reminderTime = await CorePopovers.open<{timeBefore: number}>({ component: CoreRemindersSetReminderMenuComponent, componentProps: { eventTime, diff --git a/src/addons/calendar/pages/event/event.ts b/src/addons/calendar/pages/event/event.ts index 39924a448..8cba2195a 100644 --- a/src/addons/calendar/pages/event/event.ts +++ b/src/addons/calendar/pages/event/event.ts @@ -44,6 +44,7 @@ import { CoreLocalNotifications } from '@services/local-notifications'; import { CorePlatform } from '@services/platform'; import { CoreConfig } from '@services/config'; import { CoreToasts, ToastDuration } from '@services/toasts'; +import { CorePopovers } from '@services/popovers'; /** * Page that displays a single calendar event. @@ -384,7 +385,7 @@ export class AddonCalendarEventPage implements OnInit, OnDestroy { return; } - const reminderTime = await CoreDomUtils.openPopover<{timeBefore: number}>({ + const reminderTime = await CorePopovers.open<{timeBefore: number}>({ component: CoreRemindersSetReminderMenuComponent, componentProps: { eventTime: this.event.timestart, diff --git a/src/addons/calendar/pages/settings/settings.ts b/src/addons/calendar/pages/settings/settings.ts index cb0fa0c70..eae7201f4 100644 --- a/src/addons/calendar/pages/settings/settings.ts +++ b/src/addons/calendar/pages/settings/settings.ts @@ -13,7 +13,7 @@ // limitations under the License. import { Component, OnInit } from '@angular/core'; -import { CoreDomUtils } from '@services/utils/dom'; +import { CorePopovers } from '@services/popovers'; import { CoreReminders, CoreRemindersService, @@ -51,7 +51,7 @@ export class AddonCalendarSettingsPage implements OnInit { e.stopImmediatePropagation(); e.preventDefault(); - const reminderTime = await CoreDomUtils.openPopover<{timeBefore: number}>({ + const reminderTime = await CorePopovers.open<{timeBefore: number}>({ component: CoreRemindersSetReminderMenuComponent, componentProps: { initialValue: this.defaultTime, diff --git a/src/addons/mod/data/components/action/action.ts b/src/addons/mod/data/components/action/action.ts index 57a9da66d..e254b6b93 100644 --- a/src/addons/mod/data/components/action/action.ts +++ b/src/addons/mod/data/components/action/action.ts @@ -26,7 +26,7 @@ import { } from '../../services/data'; import { AddonModDataHelper } from '../../services/data-helper'; import { AddonModDataOffline } from '../../services/data-offline'; -import { CoreDomUtils } from '@services/utils/dom'; +import { CorePopovers } from '@services/popovers'; import { AddonModDataActionsMenuComponent, AddonModDataActionsMenuItem } from '../actionsmenu/actionsmenu'; import { ADDON_MOD_DATA_ENTRY_CHANGED, @@ -202,7 +202,7 @@ export class AddonModDataActionComponent implements OnInit { }); } - await CoreDomUtils.openPopoverWithoutResult({ + await CorePopovers.openWithoutResult({ component: AddonModDataActionsMenuComponent, componentProps: { items }, id: 'actionsmenu-popover', diff --git a/src/addons/mod/forum/components/index/index.ts b/src/addons/mod/forum/components/index/index.ts index c7b7f4035..dce4ed544 100644 --- a/src/addons/mod/forum/components/index/index.ts +++ b/src/addons/mod/forum/components/index/index.ts @@ -66,6 +66,7 @@ import { } from '@addons/mod/forum/constants'; import { CoreSearchGlobalSearch } from '@features/search/services/global-search'; import { CoreToasts } from '@services/toasts'; +import { CorePopovers } from '@services/popovers'; /** * Component that displays a forum entry page. */ @@ -635,7 +636,7 @@ export class AddonModForumIndexComponent extends CoreCourseModuleMainActivityCom event.preventDefault(); event.stopPropagation(); - const popoverData = await CoreDomUtils.openPopover<{ action?: string; value: boolean }>({ + const popoverData = await CorePopovers.open<{ action?: string; value: boolean }>({ component: AddonModForumDiscussionOptionsMenuComponent, componentProps: { discussion, diff --git a/src/addons/mod/forum/components/post/post.ts b/src/addons/mod/forum/components/post/post.ts index 0662f5a32..3e4db6a7c 100644 --- a/src/addons/mod/forum/components/post/post.ts +++ b/src/addons/mod/forum/components/post/post.ts @@ -55,6 +55,7 @@ import { CoreAnalytics, CoreAnalyticsEventType } from '@services/analytics'; import { ADDON_MOD_FORUM_CHANGE_DISCUSSION_EVENT, ADDON_MOD_FORUM_COMPONENT } from '../../constants'; import { CoreToasts } from '@services/toasts'; import { toBoolean } from '@/core/transforms/boolean'; +import { CorePopovers } from '@services/popovers'; /** * Components that shows a discussion post, its attachments and the action buttons allowed (reply, etc.). @@ -233,7 +234,7 @@ export class AddonModForumPostComponent implements OnInit, OnDestroy, OnChanges * @param event Click Event. */ async showOptionsMenu(event: Event): Promise { - const popoverData = await CoreDomUtils.openPopover<{ action?: string }>({ + const popoverData = await CorePopovers.open<{ action?: string }>({ component: AddonModForumPostOptionsMenuComponent, componentProps: { post: this.post, diff --git a/src/addons/mod/glossary/components/index/index.ts b/src/addons/mod/glossary/components/index/index.ts index d8c4aca59..14d63c566 100644 --- a/src/addons/mod/glossary/components/index/index.ts +++ b/src/addons/mod/glossary/components/index/index.ts @@ -59,6 +59,7 @@ import { ADDON_MOD_GLOSSARY_ENTRY_UPDATED, ADDON_MOD_GLOSSARY_PAGE_NAME, } from '../../constants'; +import { CorePopovers } from '@services/popovers'; /** * Component that displays a glossary entry page. @@ -357,7 +358,7 @@ export class AddonModGlossaryIndexComponent extends CoreCourseModuleMainActivity const entries = await this.promisedEntries; const previousMode = entries.getSource().fetchMode; - const newMode = await CoreDomUtils.openPopover({ + const newMode = await CorePopovers.open({ component: AddonModGlossaryModePickerPopoverComponent, componentProps: { browseModes: this.glossary.browsemodes, diff --git a/src/addons/mod/quiz/classes/auto-save.ts b/src/addons/mod/quiz/classes/auto-save.ts index bbe94a4c8..9a75fed04 100644 --- a/src/addons/mod/quiz/classes/auto-save.ts +++ b/src/addons/mod/quiz/classes/auto-save.ts @@ -19,7 +19,7 @@ import { CoreQuestionsAnswers } from '@features/question/services/question'; import { CoreLogger } from '@singletons/logger'; import { AddonModQuizConnectionErrorComponent } from '../components/connection-error/connection-error'; import { AddonModQuiz, AddonModQuizAttemptWSData, AddonModQuizQuizWSData } from '../services/quiz'; -import { CoreDomUtils } from '@services/utils/dom'; +import { CorePopovers } from '@services/popovers'; /** * Class to support auto-save in quiz. Every certain seconds, it will check if there are changes in the current page answers @@ -197,7 +197,7 @@ export class AddonModQuizAutoSave { }; this.popoverShown = true; - this.popover = await CoreDomUtils.openPopoverWithoutResult({ + this.popover = await CorePopovers.openWithoutResult({ component: AddonModQuizConnectionErrorComponent, event: event, }); diff --git a/src/addons/mod/wiki/components/index/index.ts b/src/addons/mod/wiki/components/index/index.ts index 853ac31f1..3ec062614 100644 --- a/src/addons/mod/wiki/components/index/index.ts +++ b/src/addons/mod/wiki/components/index/index.ts @@ -59,6 +59,7 @@ import { ADDON_MOD_WIKI_PAGE_NAME, } from '../../constants'; import { CoreModals } from '@services/modals'; +import { CorePopovers } from '@services/popovers'; /** * Component that displays a wiki entry page. @@ -887,7 +888,7 @@ export class AddonModWikiIndexComponent extends CoreCourseModuleMainActivityComp async showSubwikiPicker(event: MouseEvent): Promise { const { AddonModWikiSubwikiPickerComponent } = await import('../subwiki-picker/subwiki-picker'); - const subwiki = await CoreDomUtils.openPopover({ + const subwiki = await CorePopovers.open({ component: AddonModWikiSubwikiPickerComponent, componentProps: { courseId: this.courseId, diff --git a/src/core/components/context-menu/context-menu.ts b/src/core/components/context-menu/context-menu.ts index bbbbca9ab..36967203d 100644 --- a/src/core/components/context-menu/context-menu.ts +++ b/src/core/components/context-menu/context-menu.ts @@ -15,7 +15,7 @@ import { Component, Input, OnInit, OnDestroy, ElementRef, ChangeDetectorRef } from '@angular/core'; import { Subject, Subscription } from 'rxjs'; import { auditTime } from 'rxjs/operators'; -import { CoreDomUtils } from '@services/utils/dom'; +import { CorePopovers } from '@services/popovers'; import { CoreUtils } from '@services/utils/utils'; import { Translate } from '@singletons'; import { CoreContextMenuItemComponent } from './context-menu-item'; @@ -183,7 +183,7 @@ export class CoreContextMenuComponent implements OnInit, OnDestroy { if (!this.expanded) { this.expanded = true; - const popoverData = await CoreDomUtils.openPopover({ + const popoverData = await CorePopovers.open({ event, component: CoreContextMenuPopoverComponent, componentProps: { diff --git a/src/core/core.module.ts b/src/core/core.module.ts index d94191d1f..214cafe38 100644 --- a/src/core/core.module.ts +++ b/src/core/core.module.ts @@ -47,6 +47,7 @@ export async function getCoreServices(): Promise[]> { const { CoreMimetypeUtilsProvider } = await import('@services/utils/mimetype'); const { CoreNavigatorService } = await import('@services/navigator'); const { CorePluginFileDelegateService } = await import('@services/plugin-file-delegate'); + const { CorePopoversService } = await import('@services/popovers'); const { CoreScreenService } = await import('@services/screen'); const { CoreSitesProvider } = await import('@services/sites'); const { CoreSyncProvider } = await import('@services/sync'); @@ -77,6 +78,7 @@ export async function getCoreServices(): Promise[]> { CoreMimetypeUtilsProvider, CoreNavigatorService, CorePluginFileDelegateService, + CorePopoversService, CorePlatformService, CoreScreenService, CoreSitesProvider, diff --git a/src/core/features/course/components/module-completion/module-completion.ts b/src/core/features/course/components/module-completion/module-completion.ts index 9962b2631..734b0a945 100644 --- a/src/core/features/course/components/module-completion/module-completion.ts +++ b/src/core/features/course/components/module-completion/module-completion.ts @@ -18,7 +18,7 @@ import { CoreCourseModuleCompletionBaseComponent } from '@features/course/classe import { CoreCourseModuleCompletionStatus, } from '@features/course/services/course'; -import { CoreDomUtils } from '@services/utils/dom'; +import { CorePopovers } from '@services/popovers'; import { CoreCourseModuleCompletionDetailsComponent } from '../module-completion-details/module-completion-details'; import { CoreCourseHelper } from '@features/course/services/course-helper'; import { CoreUser } from '@features/user/services/user'; @@ -132,7 +132,7 @@ export class CoreCourseModuleCompletionComponent target = target.parentElement; } - CoreDomUtils.openPopoverWithoutResult({ + CorePopovers.openWithoutResult({ component: CoreCourseModuleCompletionDetailsComponent, componentProps: { completion: this.completion, diff --git a/src/core/features/courses/components/course-list-item/course-list-item.ts b/src/core/features/courses/components/course-list-item/course-list-item.ts index 344cdf30b..65b00f09e 100644 --- a/src/core/features/courses/components/course-list-item/course-list-item.ts +++ b/src/core/features/courses/components/course-list-item/course-list-item.ts @@ -29,6 +29,7 @@ import { CoreCoursesCourseOptionsMenuComponent } from '../course-options-menu/co import { CoreEnrolHelper } from '@features/enrol/services/enrol-helper'; import { CoreDownloadStatusTranslatable } from '@components/download-refresh/download-refresh'; import { toBoolean } from '@/core/transforms/boolean'; +import { CorePopovers } from '@services/popovers'; /** * This directive is meant to display an item for a list of courses. @@ -297,7 +298,7 @@ export class CoreCoursesCourseListItemComponent implements OnInit, OnDestroy, On this.initPrefetchCourse(true); - const popoverData = await CoreDomUtils.openPopover({ + const popoverData = await CorePopovers.open({ component: CoreCoursesCourseOptionsMenuComponent, componentProps: { course: this.course, diff --git a/src/core/features/reminders/components/set-button/set-button.ts b/src/core/features/reminders/components/set-button/set-button.ts index b63761b87..779d7efb5 100644 --- a/src/core/features/reminders/components/set-button/set-button.ts +++ b/src/core/features/reminders/components/set-button/set-button.ts @@ -14,7 +14,7 @@ import { CoreReminderData, CoreReminders, CoreRemindersService } from '@features/reminders/services/reminders'; import { Component, Input, OnInit } from '@angular/core'; -import { CoreDomUtils } from '@services/utils/dom'; +import { CorePopovers } from '@services/popovers'; import { CoreRemindersSetReminderMenuComponent } from '../set-reminder-menu/set-reminder-menu'; import { Translate } from '@singletons'; import { CoreTimeUtils } from '@services/utils/time'; @@ -72,7 +72,7 @@ export class CoreRemindersSetButtonComponent implements OnInit { } // Open popover. - const reminderTime = await CoreDomUtils.openPopover<{timeBefore: number}>({ + const reminderTime = await CorePopovers.open<{timeBefore: number}>({ component: CoreRemindersSetReminderMenuComponent, componentProps: { initialValue: this.timebefore, diff --git a/src/core/features/reminders/components/set-reminder-menu/set-reminder-menu.ts b/src/core/features/reminders/components/set-reminder-menu/set-reminder-menu.ts index bdc6cb875..04d3c89b3 100644 --- a/src/core/features/reminders/components/set-reminder-menu/set-reminder-menu.ts +++ b/src/core/features/reminders/components/set-reminder-menu/set-reminder-menu.ts @@ -19,7 +19,7 @@ import { CoreRemindersUnits, CoreReminderValueAndUnit, } from '@features/reminders/services/reminders'; -import { CoreDomUtils } from '@services/utils/dom'; +import { CorePopovers } from '@services/popovers'; import { CoreWait } from '@singletons/wait'; import { PopoverController } from '@singletons'; import { CoreRemindersSetReminderCustomComponent } from '../set-reminder-custom/set-reminder-custom'; @@ -155,7 +155,7 @@ export class CoreRemindersSetReminderMenuComponent implements OnInit { ev.stopPropagation(); ev.preventDefault(); - const reminderTime = await CoreDomUtils.openPopover({ + const reminderTime = await CorePopovers.open({ component: CoreRemindersSetReminderCustomComponent, componentProps: { customValue: this.customValue, diff --git a/src/core/services/popovers.ts b/src/core/services/popovers.ts new file mode 100644 index 000000000..b8a08e630 --- /dev/null +++ b/src/core/services/popovers.ts @@ -0,0 +1,66 @@ +// (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 { Injectable } from '@angular/core'; +import { makeSingleton, PopoverController } from '@singletons'; +import { fixOverlayAriaHidden } from '@/core/utils/fix-aria-hidden'; +import { PopoverOptions } from '@ionic/angular'; + +/** + * Handles application popovers. + */ +@Injectable({ providedIn: 'root' }) +export class CorePopoversService { + + /** + * Opens a popover and waits for it to be dismissed to return the result. + * + * @param options Options. + * @returns Promise resolved when the popover is dismissed or will be dismissed. + */ + async open(options: OpenPopoverOptions): Promise { + const { waitForDismissCompleted, ...popoverOptions } = options; + const popover = await this.openWithoutResult(popoverOptions); + + const result = waitForDismissCompleted ? await popover.onDidDismiss() : await popover.onWillDismiss(); + if (result?.data) { + return result?.data; + } + } + + /** + * Opens a popover. + * + * @param options Options. + * @returns Promise resolved when the popover is displayed. + */ + async openWithoutResult(options: Omit): Promise { + const popover = await PopoverController.create(options); + + await popover.present(); + + fixOverlayAriaHidden(popover); + + return popover; + } + +} +export const CorePopovers = makeSingleton(CorePopoversService); + +/** + * Options for the openPopover function. + */ +export type OpenPopoverOptions = Omit & { + waitForDismissCompleted?: boolean; +}; diff --git a/src/core/services/utils/dom.ts b/src/core/services/utils/dom.ts index e5503e6ab..45273dfe0 100644 --- a/src/core/services/utils/dom.ts +++ b/src/core/services/utils/dom.ts @@ -32,7 +32,6 @@ import { makeSingleton, Translate, AlertController, - PopoverController, } from '@singletons'; import { CoreLogger } from '@singletons/logger'; import { CoreFileSizeSum } from '@services/plugin-file-delegate'; @@ -53,6 +52,7 @@ import { CoreWait } from '@singletons/wait'; import { CoreToasts, ToastDuration, ShowToastOptions } from '../toasts'; import { fixOverlayAriaHidden } from '@/core/utils/fix-aria-hidden'; import { CoreModals, OpenModalOptions } from '@services/modals'; +import { CorePopovers, OpenPopoverOptions } from '@services/popovers'; /* * "Utils" service with helper functions for UI, DOM elements and HTML code. @@ -540,7 +540,7 @@ export class CoreDomUtilsProvider { el.addEventListener('click', async (ev: Event) => { const html = el.getAttribute('data-html'); - await CoreDomUtils.openPopoverWithoutResult({ + await CorePopovers.openWithoutResult({ component: CoreBSTooltipComponent, componentProps: { content, @@ -1486,16 +1486,11 @@ export class CoreDomUtilsProvider { * * @param options Options. * @returns Promise resolved when the popover is dismissed or will be dismissed. + * + * @deprecated since 4.5. Use CorePopovers.open instead. */ async openPopover(options: OpenPopoverOptions): Promise { - - const { waitForDismissCompleted, ...popoverOptions } = options; - const popover = await this.openPopoverWithoutResult(popoverOptions); - - const result = waitForDismissCompleted ? await popover.onDidDismiss() : await popover.onWillDismiss(); - if (result?.data) { - return result?.data; - } + return CorePopovers.open(options); } /** @@ -1503,15 +1498,11 @@ export class CoreDomUtilsProvider { * * @param options Options. * @returns Promise resolved when the popover is displayed. + * + * @deprecated since 4.5. Use CorePopovers.openWithoutResult instead. */ async openPopoverWithoutResult(options: Omit): Promise { - const popover = await PopoverController.create(options); - - await popover.present(); - - fixOverlayAriaHidden(popover); - - return popover; + return CorePopovers.openWithoutResult(options); } /** @@ -1686,13 +1677,6 @@ export class CoreDomUtilsProvider { export const CoreDomUtils = makeSingleton(CoreDomUtilsProvider); -/** - * Options for the openPopover function. - */ -export type OpenPopoverOptions = Omit & { - waitForDismissCompleted?: boolean; -}; - /** * Buttons for prompt alert. */