From d6007c2aaee1b5ce27ce1cef88295c5cdf538aea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Mon, 29 Jul 2024 11:46:23 +0200 Subject: [PATCH] MOBILE-4616 chore: Create CoreToastsService to add toasts functions --- src/addons/calendar/pages/event/event.ts | 15 ++- src/addons/mod/assign/pages/edit/edit.ts | 5 +- src/addons/mod/data/services/data-helper.ts | 19 ++-- .../discussion-options-menu.ts | 16 +++- .../mod/forum/components/index/index.ts | 6 +- src/addons/mod/forum/components/post/post.ts | 6 +- .../mod/forum/pages/discussion/discussion.ts | 16 +++- src/addons/mod/glossary/pages/entry/entry.ts | 9 +- src/addons/notes/components/add/add-modal.ts | 9 +- src/addons/notes/pages/list/list.ts | 9 +- .../services/privatefiles-helper.ts | 7 +- .../insights/services/handlers/action-link.ts | 14 ++- src/core/classes/sites/authenticated-site.ts | 8 +- src/core/core.module.ts | 2 + .../features/comments/pages/viewer/viewer.ts | 19 ++-- .../components/contactdpo/contactdpo.ts | 9 +- .../components/newrequest/newrequest.ts | 9 +- .../services/fileuploader-helper.ts | 7 +- .../features/rating/components/rate/rate.ts | 9 +- .../components/set-button/set-button.ts | 10 +- src/core/features/settings/pages/dev/dev.ts | 12 ++- .../settings/pages/deviceinfo/deviceinfo.ts | 7 +- src/core/features/settings/pages/site/site.ts | 6 +- .../pages/synchronization/synchronization.ts | 6 +- .../siteplugins/directives/call-ws.ts | 4 +- src/core/services/toasts.ts | 75 +++++++++++++++ src/core/services/utils/dom.ts | 95 ++++--------------- src/core/singletons/text.ts | 7 +- src/core/utils/fix-aria-hidden.ts | 50 ++++++++++ src/types/config.d.ts | 2 +- 30 files changed, 330 insertions(+), 138 deletions(-) create mode 100644 src/core/services/toasts.ts create mode 100644 src/core/utils/fix-aria-hidden.ts diff --git a/src/addons/calendar/pages/event/event.ts b/src/addons/calendar/pages/event/event.ts index 490aec001..39924a448 100644 --- a/src/addons/calendar/pages/event/event.ts +++ b/src/addons/calendar/pages/event/event.ts @@ -24,7 +24,7 @@ import { AddonCalendarOffline } from '../../services/calendar-offline'; import { AddonCalendarSync, AddonCalendarSyncEvents, AddonCalendarSyncProvider } from '../../services/calendar-sync'; import { CoreNetwork } from '@services/network'; import { CoreEventObserver, CoreEvents } from '@singletons/events'; -import { CoreDomUtils, ToastDuration } from '@services/utils/dom'; +import { CoreDomUtils } from '@services/utils/dom'; import { CoreTextUtils } from '@services/utils/text'; import { CoreSites } from '@services/sites'; import { CoreCourse } from '@features/course/services/course'; @@ -43,6 +43,7 @@ import { CoreRemindersSetReminderMenuComponent } from '@features/reminders/compo import { CoreLocalNotifications } from '@services/local-notifications'; import { CorePlatform } from '@services/platform'; import { CoreConfig } from '@services/config'; +import { CoreToasts, ToastDuration } from '@services/toasts'; /** * Page that displays a single calendar event. @@ -556,7 +557,11 @@ export class AddonCalendarEventPage implements OnInit, OnDestroy { } if (onlineEventDeleted || this.event.id < 0) { - CoreDomUtils.showToast('addon.calendar.eventcalendareventdeleted', true, ToastDuration.LONG); + CoreToasts.show({ + message: 'addon.calendar.eventcalendareventdeleted', + translateMessage: true, + duration: ToastDuration.LONG, + }); // Event deleted, close the view. CoreNavigator.back(); @@ -611,7 +616,11 @@ export class AddonCalendarEventPage implements OnInit, OnDestroy { } if (data.deleted && data.deleted.indexOf(this.eventId) != -1) { - CoreDomUtils.showToast('addon.calendar.eventcalendareventdeleted', true, ToastDuration.LONG); + CoreToasts.show({ + message: 'addon.calendar.eventcalendareventdeleted', + translateMessage: true, + duration: ToastDuration.LONG, + }); // Event was deleted, close the view. CoreNavigator.back(); diff --git a/src/addons/mod/assign/pages/edit/edit.ts b/src/addons/mod/assign/pages/edit/edit.ts index e421deaf0..836927079 100644 --- a/src/addons/mod/assign/pages/edit/edit.ts +++ b/src/addons/mod/assign/pages/edit/edit.ts @@ -20,7 +20,7 @@ import { CanLeave } from '@guards/can-leave'; import { CoreNavigator } from '@services/navigator'; import { CoreSites, CoreSitesReadingStrategy } from '@services/sites'; import { CoreSync } from '@services/sync'; -import { CoreDomUtils, ToastDuration } from '@services/utils/dom'; +import { CoreDomUtils } from '@services/utils/dom'; import { CoreFormFields, CoreForms } from '@singletons/form'; import { Translate } from '@singletons'; import { CoreEvents } from '@singletons/events'; @@ -45,6 +45,7 @@ import { ADDON_MOD_ASSIGN_SUBMISSION_SAVED_EVENT, ADDON_MOD_ASSIGN_SUBMITTED_FOR_GRADING_EVENT, } from '../../constants'; +import { CoreToasts, ToastDuration } from '@services/toasts'; /** * Page that allows adding or editing an assigment submission. @@ -488,7 +489,7 @@ export class AddonModAssignEditPage implements OnInit, OnDestroy, CanLeave { * Function called when the time is up. */ async timeUp(): Promise { - this.timeUpToast = await CoreDomUtils.showToastWithOptions({ + this.timeUpToast = await CoreToasts.show({ message: Translate.instant('addon.mod_assign.caneditsubmission'), duration: ToastDuration.STICKY, buttons: [Translate.instant('core.dismiss')], diff --git a/src/addons/mod/data/services/data-helper.ts b/src/addons/mod/data/services/data-helper.ts index ee443d507..faaeeb5f9 100644 --- a/src/addons/mod/data/services/data-helper.ts +++ b/src/addons/mod/data/services/data-helper.ts @@ -19,7 +19,7 @@ import { CoreFileUploader, CoreFileUploaderStoreFilesResult } from '@features/fi import { CoreRatingOffline } from '@features/rating/services/rating-offline'; import { FileEntry } from '@awesome-cordova-plugins/file/ngx'; import { CoreSites, CoreSitesReadingStrategy } from '@services/sites'; -import { CoreDomUtils, ToastDuration } from '@services/utils/dom'; +import { CoreDomUtils } from '@services/utils/dom'; import { CoreFormFields } from '@singletons/form'; import { CoreTextUtils } from '@services/utils/text'; import { CoreUtils } from '@services/utils/utils'; @@ -47,6 +47,7 @@ import { AddonModDataTemplateType, AddonModDataTemplateMode, } from '../constants'; +import { CoreToasts, ToastDuration } from '@services/toasts'; /** * Service that provides helper functions for datas. @@ -176,11 +177,11 @@ export class AddonModDataHelperProvider { CoreEvents.trigger(ADDON_MOD_DATA_ENTRY_CHANGED, { dataId: dataId, entryId: entryId }, siteId); - CoreDomUtils.showToast( - approve ? 'addon.mod_data.recordapproved' : 'addon.mod_data.recorddisapproved', - true, - ToastDuration.LONG, - ); + CoreToasts.show({ + message: approve ? 'addon.mod_data.recordapproved' : 'addon.mod_data.recorddisapproved', + translateMessage: true, + duration: ToastDuration.LONG, + }); } catch { // Ignore error, it was already displayed. } finally { @@ -883,7 +884,11 @@ export class AddonModDataHelperProvider { CoreEvents.trigger(ADDON_MOD_DATA_ENTRY_CHANGED, { dataId, entryId, deleted: true }, siteId); - CoreDomUtils.showToast('addon.mod_data.recorddeleted', true, ToastDuration.LONG); + CoreToasts.show({ + message: 'addon.mod_data.recorddeleted', + translateMessage: true, + duration: ToastDuration.LONG, + }); modal.dismiss(); } catch { diff --git a/src/addons/mod/forum/components/discussion-options-menu/discussion-options-menu.ts b/src/addons/mod/forum/components/discussion-options-menu/discussion-options-menu.ts index 77dfa2971..0eb646d2d 100644 --- a/src/addons/mod/forum/components/discussion-options-menu/discussion-options-menu.ts +++ b/src/addons/mod/forum/components/discussion-options-menu/discussion-options-menu.ts @@ -19,6 +19,7 @@ import { PopoverController } from '@singletons'; import { CoreEvents } from '@singletons/events'; import { AddonModForum, AddonModForumDiscussion } from '../../services/forum'; import { ADDON_MOD_FORUM_CHANGE_DISCUSSION_EVENT } from '../../constants'; +import { CoreToasts } from '@services/toasts'; /** * This component is meant to display a popover with the discussion options. @@ -74,7 +75,10 @@ export class AddonModForumDiscussionOptionsMenuComponent implements OnInit { CoreEvents.trigger(ADDON_MOD_FORUM_CHANGE_DISCUSSION_EVENT, data, CoreSites.getCurrentSiteId()); PopoverController.dismiss({ action: 'lock', value: locked }); - CoreDomUtils.showToast('addon.mod_forum.lockupdated', true); + CoreToasts.show({ + message: 'addon.mod_forum.lockupdated', + translateMessage: true, + }); } catch (error) { CoreDomUtils.showErrorModal(error); PopoverController.dismiss(); @@ -103,7 +107,10 @@ export class AddonModForumDiscussionOptionsMenuComponent implements OnInit { CoreEvents.trigger(ADDON_MOD_FORUM_CHANGE_DISCUSSION_EVENT, data, CoreSites.getCurrentSiteId()); PopoverController.dismiss({ action: 'pin', value: pinned }); - CoreDomUtils.showToast('addon.mod_forum.pinupdated', true); + CoreToasts.show({ + message: 'addon.mod_forum.pinupdated', + translateMessage: true, + }); } catch (error) { CoreDomUtils.showErrorModal(error); PopoverController.dismiss(); @@ -132,7 +139,10 @@ export class AddonModForumDiscussionOptionsMenuComponent implements OnInit { CoreEvents.trigger(ADDON_MOD_FORUM_CHANGE_DISCUSSION_EVENT, data, CoreSites.getCurrentSiteId()); PopoverController.dismiss({ action: 'star', value: starred }); - CoreDomUtils.showToast('addon.mod_forum.favouriteupdated', true); + CoreToasts.show({ + message: 'addon.mod_forum.favouriteupdated', + translateMessage: true, + }); } catch (error) { CoreDomUtils.showErrorModal(error); PopoverController.dismiss(); diff --git a/src/addons/mod/forum/components/index/index.ts b/src/addons/mod/forum/components/index/index.ts index 7746222cd..c7b7f4035 100644 --- a/src/addons/mod/forum/components/index/index.ts +++ b/src/addons/mod/forum/components/index/index.ts @@ -65,6 +65,7 @@ import { ADDON_MOD_FORUM_SEARCH_PAGE_NAME, } from '@addons/mod/forum/constants'; import { CoreSearchGlobalSearch } from '@features/search/services/global-search'; +import { CoreToasts } from '@services/toasts'; /** * Component that displays a forum entry page. */ @@ -554,7 +555,10 @@ export class AddonModForumIndexComponent extends CoreCourseModuleMainActivityCom try { if (isNewDiscussion) { - CoreDomUtils.showToast('addon.mod_forum.postaddedsuccess', true); + CoreToasts.show({ + message: 'addon.mod_forum.postaddedsuccess', + translateMessage: true, + }); const newDiscGroupId = (data as AddonModForumNewDiscussionData).groupId; diff --git a/src/addons/mod/forum/components/post/post.ts b/src/addons/mod/forum/components/post/post.ts index 49f7b0db0..759782675 100644 --- a/src/addons/mod/forum/components/post/post.ts +++ b/src/addons/mod/forum/components/post/post.ts @@ -53,6 +53,7 @@ import { AddonModForumSharedPostFormData } from '../../pages/discussion/discussi import { CoreDom } from '@singletons/dom'; import { CoreAnalytics, CoreAnalyticsEventType } from '@services/analytics'; import { ADDON_MOD_FORUM_CHANGE_DISCUSSION_EVENT, ADDON_MOD_FORUM_COMPONENT } from '../../constants'; +import { CoreToasts } from '@services/toasts'; /** * Components that shows a discussion post, its attachments and the action buttons allowed (reply, etc.). @@ -167,7 +168,10 @@ export class AddonModForumPostComponent implements OnInit, OnDestroy, OnChanges CoreSites.getCurrentSiteId(), ); - CoreDomUtils.showToast('addon.mod_forum.deletedpost', true); + CoreToasts.show({ + message: 'addon.mod_forum.deletedpost', + translateMessage: true, + }); } catch (error) { CoreDomUtils.showErrorModal(error); } finally { diff --git a/src/addons/mod/forum/pages/discussion/discussion.ts b/src/addons/mod/forum/pages/discussion/discussion.ts index 522ec6a07..ea1d5b137 100644 --- a/src/addons/mod/forum/pages/discussion/discussion.ts +++ b/src/addons/mod/forum/pages/discussion/discussion.ts @@ -59,6 +59,7 @@ import { ADDON_MOD_FORUM_REPLY_DISCUSSION_EVENT, } from '../../constants'; import { CoreCourseContentsPage } from '@features/course/pages/contents/contents'; +import { CoreToasts } from '@services/toasts'; type SortType = 'flat-newest' | 'flat-oldest' | 'nested'; @@ -730,7 +731,10 @@ export class AddonModForumDiscussionPage implements OnInit, AfterViewInit, OnDes }; CoreEvents.trigger(ADDON_MOD_FORUM_CHANGE_DISCUSSION_EVENT, data, CoreSites.getCurrentSiteId()); - CoreDomUtils.showToast('addon.mod_forum.lockupdated', true); + CoreToasts.show({ + message: 'addon.mod_forum.lockupdated', + translateMessage: true, + }); } catch (error) { CoreDomUtils.showErrorModal(error); } finally { @@ -763,7 +767,10 @@ export class AddonModForumDiscussionPage implements OnInit, AfterViewInit, OnDes }; CoreEvents.trigger(ADDON_MOD_FORUM_CHANGE_DISCUSSION_EVENT, data, CoreSites.getCurrentSiteId()); - CoreDomUtils.showToast('addon.mod_forum.pinupdated', true); + CoreToasts.show({ + message: 'addon.mod_forum.pinupdated', + translateMessage: true, + }); } catch (error) { CoreDomUtils.showErrorModal(error); } finally { @@ -796,7 +803,10 @@ export class AddonModForumDiscussionPage implements OnInit, AfterViewInit, OnDes }; CoreEvents.trigger(ADDON_MOD_FORUM_CHANGE_DISCUSSION_EVENT, data, CoreSites.getCurrentSiteId()); - CoreDomUtils.showToast('addon.mod_forum.favouriteupdated', true); + CoreToasts.show({ + message: 'addon.mod_forum.favouriteupdated', + translateMessage: true, + }); } catch (error) { CoreDomUtils.showErrorModal(error); } finally { diff --git a/src/addons/mod/glossary/pages/entry/entry.ts b/src/addons/mod/glossary/pages/entry/entry.ts index 7b55531ff..19e5637ce 100644 --- a/src/addons/mod/glossary/pages/entry/entry.ts +++ b/src/addons/mod/glossary/pages/entry/entry.ts @@ -26,7 +26,7 @@ import { CoreTag } from '@features/tag/services/tag'; import { FileEntry } from '@awesome-cordova-plugins/file/ngx'; import { CoreNavigator } from '@services/navigator'; import { CoreNetwork } from '@services/network'; -import { CoreDomUtils, ToastDuration } from '@services/utils/dom'; +import { CoreDomUtils } from '@services/utils/dom'; import { CoreUtils } from '@services/utils/utils'; import { Translate } from '@singletons'; import { CoreEventObserver, CoreEvents } from '@singletons/events'; @@ -40,6 +40,7 @@ import { CoreTime } from '@singletons/time'; import { CoreAnalytics, CoreAnalyticsEventType } from '@services/analytics'; import { ADDON_MOD_GLOSSARY_COMPONENT, ADDON_MOD_GLOSSARY_ENTRY_UPDATED, ADDON_MOD_GLOSSARY_PAGE_NAME } from '../../constants'; import { CoreCourseContentsPage } from '@features/course/pages/contents/contents'; +import { CoreToasts, ToastDuration } from '@services/toasts'; /** * Page that displays a glossary entry. @@ -214,7 +215,11 @@ export class AddonModGlossaryEntryPage implements OnInit, OnDestroy { await AddonModGlossaryHelper.deleteStoredFiles(glossaryId, concept, timecreated); } - CoreDomUtils.showToast('addon.mod_glossary.entrydeleted', true, ToastDuration.LONG); + CoreToasts.show({ + message: 'addon.mod_glossary.entrydeleted', + translateMessage: true, + duration: ToastDuration.LONG, + }); await this.goBack(); } catch (error) { diff --git a/src/addons/notes/components/add/add-modal.ts b/src/addons/notes/components/add/add-modal.ts index 1fdf03ea8..337b97dc6 100644 --- a/src/addons/notes/components/add/add-modal.ts +++ b/src/addons/notes/components/add/add-modal.ts @@ -15,11 +15,12 @@ import { AddonNotes, AddonNotesPublishState } from '@addons/notes/services/notes'; import { Component, ViewChild, ElementRef, Input } from '@angular/core'; import { CoreSites } from '@services/sites'; -import { CoreDomUtils, ToastDuration } from '@services/utils/dom'; +import { CoreDomUtils } from '@services/utils/dom'; import { CoreForms } from '@singletons/form'; import { ModalController } from '@singletons'; import { CoreKeyboard } from '@singletons/keyboard'; import { CoreSharedModule } from '@/core/shared.module'; +import { CoreToasts, ToastDuration } from '@services/toasts'; /** * Component that displays a text area for composing a note. @@ -62,7 +63,11 @@ export class AddonNotesAddComponent { CoreForms.triggerFormSubmittedEvent(this.formElement, sent, CoreSites.getCurrentSiteId()); ModalController.dismiss({ type: this.type, sent: true }).finally(() => { - CoreDomUtils.showToast(sent ? 'addon.notes.eventnotecreated' : 'core.datastoredoffline', true, ToastDuration.LONG); + CoreToasts.show({ + message: sent ? 'addon.notes.eventnotecreated' : 'core.datastoredoffline', + translateMessage: true, + duration: ToastDuration.LONG, + }); }); } catch (error){ CoreDomUtils.showErrorModal(error); diff --git a/src/addons/notes/pages/list/list.ts b/src/addons/notes/pages/list/list.ts index b31a6ac17..840ef91dd 100644 --- a/src/addons/notes/pages/list/list.ts +++ b/src/addons/notes/pages/list/list.ts @@ -24,13 +24,14 @@ import { IonContent } from '@ionic/angular'; import { CoreAnalytics, CoreAnalyticsEventType } from '@services/analytics'; import { CoreNavigator } from '@services/navigator'; import { CoreSites } from '@services/sites'; -import { CoreDomUtils, ToastDuration } from '@services/utils/dom'; +import { CoreDomUtils } from '@services/utils/dom'; import { CoreTextUtils } from '@services/utils/text'; import { CoreUrl } from '@singletons/url'; import { CoreUtils } from '@services/utils/utils'; import { Translate } from '@singletons'; import { CoreEventObserver, CoreEvents } from '@singletons/events'; import { CoreTime } from '@singletons/time'; +import { CoreToasts, ToastDuration } from '@services/toasts'; /** * Page that displays a list of notes. @@ -240,7 +241,11 @@ export class AddonNotesListPage implements OnInit, OnDestroy { this.refreshNotes(false); - CoreDomUtils.showToast('addon.notes.eventnotedeleted', true, ToastDuration.LONG); + CoreToasts.show({ + message: 'addon.notes.eventnotedeleted', + translateMessage: true, + duration: ToastDuration.LONG, + }); } catch (error) { CoreDomUtils.showErrorModalDefault(error, 'Delete note failed.'); diff --git a/src/addons/privatefiles/services/privatefiles-helper.ts b/src/addons/privatefiles/services/privatefiles-helper.ts index a00f2bd94..b12cd780a 100644 --- a/src/addons/privatefiles/services/privatefiles-helper.ts +++ b/src/addons/privatefiles/services/privatefiles-helper.ts @@ -20,6 +20,7 @@ import { CoreFileUploaderHelper } from '@features/fileuploader/services/fileuplo import { AddonPrivateFiles, AddonPrivateFilesGetUserInfoWSResult } from './privatefiles'; import { CoreError } from '@classes/errors/error'; import { makeSingleton, Translate } from '@singletons'; +import { CoreToasts } from '@services/toasts'; /** * Service that provides some helper functions regarding private and site files. @@ -64,7 +65,11 @@ export class AddonPrivateFilesHelperProvider { try { await AddonPrivateFiles.moveFromDraftToPrivate(result.itemid); - CoreDomUtils.showToast('core.fileuploader.fileuploaded', true, undefined, 'core-toast-success'); + CoreToasts.show({ + message: 'core.fileuploader.fileuploaded', + translateMessage: true, + cssClass: 'core-toast-success', + }); } finally { modal.dismiss(); } diff --git a/src/addons/report/insights/services/handlers/action-link.ts b/src/addons/report/insights/services/handlers/action-link.ts index e91ce2386..679ae22d6 100644 --- a/src/addons/report/insights/services/handlers/action-link.ts +++ b/src/addons/report/insights/services/handlers/action-link.ts @@ -20,6 +20,7 @@ import { CoreSites } from '@services/sites'; import { CoreDomUtils } from '@services/utils/dom'; import { makeSingleton, Translate } from '@singletons'; import { AddonReportInsights } from '../insights'; +import { CoreToasts } from '@services/toasts'; // Bulk actions supported, along with the related lang string. const BULK_ACTIONS = { @@ -64,12 +65,17 @@ export class AddonReportInsightsActionLinkHandlerService extends CoreContentLink if (BULK_ACTIONS[params.action]) { // Done, display a toast. - CoreDomUtils.showToast(Translate.instant('addon.report_insights.actionsaved', { - $a: Translate.instant(BULK_ACTIONS[params.action]), - })); + CoreToasts.show({ + message: Translate.instant('addon.report_insights.actionsaved', { + $a: Translate.instant(BULK_ACTIONS[params.action]), + }), + }); } else if (!params.forwardurl) { // Forward URL not defined, display a toast. - CoreDomUtils.showToast('core.success', true); + CoreToasts.show({ + message: 'core.success', + translateMessage: true, + }); } else { // Try to open the link in the app. const forwardUrl = decodeURIComponent(params.forwardurl); diff --git a/src/core/classes/sites/authenticated-site.ts b/src/core/classes/sites/authenticated-site.ts index 20be3c9fe..a40896b9e 100644 --- a/src/core/classes/sites/authenticated-site.ts +++ b/src/core/classes/sites/authenticated-site.ts @@ -21,7 +21,7 @@ import { CoreWSPreSetsSplitRequest, CoreWSTypeExpected, } from '@services/ws'; -import { CoreDomUtils, ToastDuration } from '@services/utils/dom'; +import { CoreToasts, ToastDuration } from '@services/toasts'; import { CoreTextUtils } from '@services/utils/text'; import { CoreUtils } from '@services/utils/utils'; import { CoreConstants } from '@/core/constants'; @@ -420,7 +420,11 @@ export class CoreAuthenticatedSite extends CoreUnauthenticatedSite { if (wsPreSets.cleanUnicode && CoreTextUtils.hasUnicodeData(data)) { // Data will be cleaned, notify the user. - CoreDomUtils.showToast('core.unicodenotsupported', true, ToastDuration.LONG); + CoreToasts.show({ + message: 'core.unicodenotsupported', + translateMessage: true, + duration: ToastDuration.LONG, + }); } else { // No need to clean data in this call. wsPreSets.cleanUnicode = false; diff --git a/src/core/core.module.ts b/src/core/core.module.ts index 5a33b79e3..d94191d1f 100644 --- a/src/core/core.module.ts +++ b/src/core/core.module.ts @@ -34,6 +34,7 @@ export async function getCoreServices(): Promise[]> { const { CoreCustomURLSchemesProvider } = await import('@services/urlschemes'); const { CoreDbProvider } = await import('@services/db'); const { CoreDomUtilsProvider } = await import('@services/utils/dom'); + const { CoreToastsService } = await import('@services/toasts'); const { CoreFileHelperProvider } = await import('@services/file-helper'); const { CoreFilepoolProvider } = await import('@services/filepool'); const { CoreFileProvider } = await import('@services/file'); @@ -82,6 +83,7 @@ export async function getCoreServices(): Promise[]> { CoreSyncProvider, CoreTextUtilsProvider, CoreTimeUtilsProvider, + CoreToastsService, CoreUpdateManagerProvider, CoreUrlUtilsProvider, CoreUtilsProvider, diff --git a/src/core/features/comments/pages/viewer/viewer.ts b/src/core/features/comments/pages/viewer/viewer.ts index e1a077947..a403084b6 100644 --- a/src/core/features/comments/pages/viewer/viewer.ts +++ b/src/core/features/comments/pages/viewer/viewer.ts @@ -31,7 +31,7 @@ import { ContextLevel, CoreConstants } from '@/core/constants'; import { CoreNavigator } from '@services/navigator'; import { NgZone, Translate } from '@singletons'; import { CoreUtils } from '@services/utils/utils'; -import { CoreDomUtils, ToastDuration } from '@services/utils/dom'; +import { CoreDomUtils } from '@services/utils/dom'; import { CoreUser } from '@features/user/services/user'; import { CoreTextUtils } from '@services/utils/text'; import { CoreError } from '@classes/errors/error'; @@ -43,6 +43,7 @@ import moment from 'moment-timezone'; import { Subscription } from 'rxjs'; import { CoreAnimations } from '@components/animations'; import { CoreKeyboard } from '@singletons/keyboard'; +import { CoreToasts, ToastDuration } from '@services/toasts'; /** * Page that displays comments. @@ -323,11 +324,11 @@ export class CoreCommentsViewerPage implements OnInit, OnDestroy { this.area, ); - CoreDomUtils.showToast( - commentsResponse ? 'core.comments.eventcommentcreated' : 'core.datastoredoffline', - true, - ToastDuration.LONG, - ); + CoreToasts.show({ + message: commentsResponse ? 'core.comments.eventcommentcreated' : 'core.datastoredoffline', + translateMessage: true, + duration: ToastDuration.LONG, + }); if (commentsResponse) { this.invalidateComments(); @@ -426,7 +427,11 @@ export class CoreCommentsViewerPage implements OnInit, OnDestroy { this.invalidateComments(); - CoreDomUtils.showToast('core.comments.eventcommentdeleted', true, ToastDuration.LONG); + CoreToasts.show({ + message: 'core.comments.eventcommentdeleted', + translateMessage: true, + duration: ToastDuration.LONG, + }); } catch (error) { CoreDomUtils.showErrorModalDefault(error, 'Delete comment failed.'); } diff --git a/src/core/features/dataprivacy/components/contactdpo/contactdpo.ts b/src/core/features/dataprivacy/components/contactdpo/contactdpo.ts index 6bcd74ba6..dc210b959 100644 --- a/src/core/features/dataprivacy/components/contactdpo/contactdpo.ts +++ b/src/core/features/dataprivacy/components/contactdpo/contactdpo.ts @@ -18,7 +18,8 @@ import { FormGroup, FormBuilder, Validators } from '@angular/forms'; import { CoreDataPrivacy } from '@features/dataprivacy/services/dataprivacy'; import { CoreUser } from '@features/user/services/user'; import { CoreSites } from '@services/sites'; -import { CoreDomUtils, ToastDuration } from '@services/utils/dom'; +import { CoreDomUtils } from '@services/utils/dom'; +import { CoreToasts, ToastDuration } from '@services/toasts'; import { CoreUtils } from '@services/utils/utils'; import { ModalController } from '@singletons'; @@ -80,7 +81,11 @@ export class CoreDataPrivacyContactDPOComponent implements OnInit { // Send the message. const succeed = await CoreDataPrivacy.contactDPO(this.message); if (succeed) { - CoreDomUtils.showToast('core.dataprivacy.requestsubmitted', true, ToastDuration.LONG); + CoreToasts.show({ + message: 'core.dataprivacy.requestsubmitted', + translateMessage: true, + duration: ToastDuration.LONG, + }); ModalController.dismiss(true); } } catch (error) { diff --git a/src/core/features/dataprivacy/components/newrequest/newrequest.ts b/src/core/features/dataprivacy/components/newrequest/newrequest.ts index 7939da1fd..53fde8914 100644 --- a/src/core/features/dataprivacy/components/newrequest/newrequest.ts +++ b/src/core/features/dataprivacy/components/newrequest/newrequest.ts @@ -20,7 +20,8 @@ import { CoreDataPrivacyDataRequestType, CoreDataPrivacyGetAccessInformationWSResponse, } from '@features/dataprivacy/services/dataprivacy'; -import { CoreDomUtils, ToastDuration } from '@services/utils/dom'; +import { CoreDomUtils } from '@services/utils/dom'; +import { CoreToasts, ToastDuration } from '@services/toasts'; import { ModalController } from '@singletons'; @@ -105,7 +106,11 @@ export class CoreDataPrivacyNewRequestComponent implements OnInit { // Send the message. const requestId = await CoreDataPrivacy.createDataRequest(this.typeControl.value, this.message); if (requestId) { - CoreDomUtils.showToast('core.dataprivacy.requestsubmitted', true, ToastDuration.LONG); + CoreToasts.show({ + message: 'core.dataprivacy.requestsubmitted', + translateMessage: true, + duration: ToastDuration.LONG, + }); ModalController.dismiss(true); } } catch (error) { diff --git a/src/core/features/fileuploader/services/fileuploader-helper.ts b/src/core/features/fileuploader/services/fileuploader-helper.ts index 1d6a8cf76..cbbad35a1 100644 --- a/src/core/features/fileuploader/services/fileuploader-helper.ts +++ b/src/core/features/fileuploader/services/fileuploader-helper.ts @@ -44,6 +44,7 @@ import { CorePath } from '@singletons/path'; import { CorePromisedValue } from '@classes/promised-value'; import { CorePlatform } from '@services/platform'; import { Chooser } from '@features/native/plugins'; +import { CoreToasts } from '@services/toasts'; /** * Helper service to upload files. @@ -457,7 +458,11 @@ export class CoreFileUploaderHelperProvider { await this.uploadGenericFile(CoreFile.getFileEntryURL(fileEntry), file.name, file.type, deleteAfterUpload, siteId); - CoreDomUtils.showToast('core.fileuploader.fileuploaded', true, undefined, 'core-toast-success'); + CoreToasts.show({ + message: 'core.fileuploader.fileuploaded', + translateMessage: true, + cssClass: 'core-toast-success', + }); } catch (error) { CoreDomUtils.showErrorModalDefault(error, 'core.fileuploader.errorreadingfile', true); diff --git a/src/core/features/rating/components/rate/rate.ts b/src/core/features/rating/components/rate/rate.ts index fdd30b0e5..a7b9c562e 100644 --- a/src/core/features/rating/components/rate/rate.ts +++ b/src/core/features/rating/components/rate/rate.ts @@ -23,7 +23,8 @@ import { } from '@features/rating/services/rating'; import { CoreRatingOffline } from '@features/rating/services/rating-offline'; import { CoreSites } from '@services/sites'; -import { CoreDomUtils, ToastDuration } from '@services/utils/dom'; +import { CoreDomUtils } from '@services/utils/dom'; +import { CoreToasts, ToastDuration } from '@services/toasts'; import { Translate } from '@singletons'; import { CoreEventObserver, CoreEvents } from '@singletons/events'; @@ -147,7 +148,11 @@ export class CoreRatingRateComponent implements OnChanges, OnDestroy { ); if (response === undefined) { - CoreDomUtils.showToast('core.datastoredoffline', true, ToastDuration.LONG); + CoreToasts.show({ + message: 'core.datastoredoffline', + translateMessage: true, + duration: ToastDuration.LONG, + }); } else { this.onUpdate.emit(); } 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 a775ad6a8..b63761b87 100644 --- a/src/core/features/reminders/components/set-button/set-button.ts +++ b/src/core/features/reminders/components/set-button/set-button.ts @@ -18,6 +18,7 @@ import { CoreDomUtils } from '@services/utils/dom'; import { CoreRemindersSetReminderMenuComponent } from '../set-reminder-menu/set-reminder-menu'; import { Translate } from '@singletons'; import { CoreTimeUtils } from '@services/utils/time'; +import { CoreToasts } from '@services/toasts'; /** * Component that displays a button to set a reminder. @@ -127,7 +128,10 @@ export class CoreRemindersSetButtonComponent implements OnInit { if (timebefore === undefined || timebefore === CoreRemindersService.DISABLED) { this.setTimebefore(undefined); - CoreDomUtils.showToast('core.reminders.reminderunset', true); + CoreToasts.show({ + message: 'core.reminders.reminderunset', + translateMessage: true, + }); return; } @@ -148,8 +152,8 @@ export class CoreRemindersSetButtonComponent implements OnInit { await CoreReminders.addReminder(reminder); const time = this.time - timebefore; - const text = Translate.instant('core.reminders.reminderset', { $a: CoreTimeUtils.userDate(time * 1000) }); - CoreDomUtils.showToast(text); + const message = Translate.instant('core.reminders.reminderset', { $a: CoreTimeUtils.userDate(time * 1000) }); + CoreToasts.show({ message }); } } diff --git a/src/core/features/settings/pages/dev/dev.ts b/src/core/features/settings/pages/dev/dev.ts index ce9bac44b..8b2888399 100644 --- a/src/core/features/settings/pages/dev/dev.ts +++ b/src/core/features/settings/pages/dev/dev.ts @@ -24,7 +24,8 @@ import { CoreFile } from '@services/file'; import { CoreNavigator } from '@services/navigator'; import { CorePlatform } from '@services/platform'; import { CoreSites } from '@services/sites'; -import { CoreDomUtils, ToastDuration } from '@services/utils/dom'; +import { CoreDomUtils } from '@services/utils/dom'; +import { CoreToasts, ToastDuration } from '@services/toasts'; import { CoreText } from '@singletons/text'; /** @@ -177,7 +178,7 @@ export class CoreSettingsDevPage implements OnInit { await CoreConfig.delete(ONBOARDING_DONE); await CoreConfig.delete(FAQ_QRCODE_INFO_DONE); - CoreDomUtils.showToast('User tours have been reseted'); + CoreToasts.show({ message: 'User tours have been reseted' }); } /** @@ -194,7 +195,10 @@ export class CoreSettingsDevPage implements OnInit { return; } - await CoreDomUtils.showToast('Caches invalidated', true, ToastDuration.LONG); + await CoreToasts.show({ + message: 'Caches invalidated', + duration: ToastDuration.LONG, + }); } /** @@ -205,7 +209,7 @@ export class CoreSettingsDevPage implements OnInit { await CoreFile.clearDeletedSitesFolder(sites); await CoreFile.clearTmpFolder(); - CoreDomUtils.showToast('File storage cleared'); + CoreToasts.show({ message: 'File storage cleared' }); } async setEnabledStagingSites(enabled: boolean): Promise { diff --git a/src/core/features/settings/pages/deviceinfo/deviceinfo.ts b/src/core/features/settings/pages/deviceinfo/deviceinfo.ts index 815976b56..38b5a45ea 100644 --- a/src/core/features/settings/pages/deviceinfo/deviceinfo.ts +++ b/src/core/features/settings/pages/deviceinfo/deviceinfo.ts @@ -23,7 +23,7 @@ import { CoreUtils } from '@services/utils/utils'; import { Subscription } from 'rxjs'; import { CorePushNotifications } from '@features/pushnotifications/services/pushnotifications'; import { CoreConfig } from '@services/config'; -import { CoreDomUtils } from '@services/utils/dom'; +import { CoreToasts } from '@services/toasts'; import { CoreNavigator } from '@services/navigator'; import { CorePlatform } from '@services/platform'; import { CoreNetwork } from '@services/network'; @@ -265,7 +265,10 @@ export class CoreSettingsDeviceInfoPage implements OnDestroy { this.showDevOptions = true; await CoreConfig.set('showDevOptions', 1); - CoreDomUtils.showToast('core.settings.youradev', true); + CoreToasts.show({ + message: 'core.settings.youradev', + translateMessage: true, + }); } else { this.showDevOptions = false; await CoreConfig.delete('showDevOptions'); diff --git a/src/core/features/settings/pages/site/site.ts b/src/core/features/settings/pages/site/site.ts index 32c0afa5f..a3575362c 100644 --- a/src/core/features/settings/pages/site/site.ts +++ b/src/core/features/settings/pages/site/site.ts @@ -29,6 +29,7 @@ import { NgZone } from '@singletons'; import { CoreConstants } from '@/core/constants'; import { CoreConfig } from '@services/config'; import { CoreSettingsHandlersSource } from '@features/settings/classes/settings-handlers-source'; +import { CoreToasts } from '@services/toasts'; /** * Page that displays the list of site settings pages. @@ -117,7 +118,10 @@ export class CoreSitePreferencesPage implements AfterViewInit, OnDestroy { // Using syncOnlyOnWifi false to force manual sync. await CoreSettingsHelper.synchronizeSite(false, this.siteId); - CoreDomUtils.showToast('core.settings.sitesynccompleted', true); + CoreToasts.show({ + message: 'core.settings.sitesynccompleted', + translateMessage: true, + }); } catch (error) { if (this.isDestroyed) { return; diff --git a/src/core/features/settings/pages/synchronization/synchronization.ts b/src/core/features/settings/pages/synchronization/synchronization.ts index 2bf02cdbf..2b778e6d3 100644 --- a/src/core/features/settings/pages/synchronization/synchronization.ts +++ b/src/core/features/settings/pages/synchronization/synchronization.ts @@ -25,6 +25,7 @@ import { CoreAccountsList, CoreLoginHelper } from '@features/login/services/logi import { CoreNetwork } from '@services/network'; import { Subscription } from 'rxjs'; import { CoreNavigator } from '@services/navigator'; +import { CoreToasts } from '@services/toasts'; /** * Page that displays the synchronization settings. @@ -132,7 +133,10 @@ export class CoreSettingsSynchronizationPage implements OnInit, OnDestroy { try { await CoreSettingsHelper.synchronizeSite(false, siteId); - CoreDomUtils.showToast('core.settings.sitesynccompleted', true); + CoreToasts.show({ + message: 'core.settings.sitesynccompleted', + translateMessage: true, + }); } catch (error) { if (this.isDestroyed) { return; diff --git a/src/core/features/siteplugins/directives/call-ws.ts b/src/core/features/siteplugins/directives/call-ws.ts index 6c232973e..fc5bc0d3a 100644 --- a/src/core/features/siteplugins/directives/call-ws.ts +++ b/src/core/features/siteplugins/directives/call-ws.ts @@ -15,7 +15,7 @@ import { Directive, Input, ElementRef, Optional } from '@angular/core'; import { Translate } from '@singletons'; -import { CoreDomUtils } from '@services/utils/dom'; +import { CoreToasts } from '@services/toasts'; import { CoreUtils } from '@services/utils/utils'; import { CoreNavigator } from '@services/navigator'; import { CoreSitePluginsCallWSOnClickBaseDirective } from '../classes/call-ws-click-directive'; @@ -74,7 +74,7 @@ export class CoreSitePluginsCallWSDirective extends CoreSitePluginsCallWSOnClick if (this.successMessage !== undefined) { // Display the success message. - CoreDomUtils.showToast(this.successMessage || Translate.instant('core.success')); + CoreToasts.show({ message: this.successMessage || Translate.instant('core.success') }); } } diff --git a/src/core/services/toasts.ts b/src/core/services/toasts.ts new file mode 100644 index 000000000..683f9496d --- /dev/null +++ b/src/core/services/toasts.ts @@ -0,0 +1,75 @@ +// (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 { CoreConstants } from '@/core/constants'; +import { Injectable } from '@angular/core'; +import { ToastOptions } from '@ionic/angular'; +import { Translate, ToastController, makeSingleton } from '@singletons'; +import { fixOverlayAriaHidden } from '@/core/utils/fix-aria-hidden'; + +/** + * Handles application toasts. + */ +@Injectable({ providedIn: 'root' }) +export class CoreToastsService { + + /** + * Displays an autodimissable toast modal window. + * + * @param options Options. + * @returns Promise resolved with Toast instance. + */ + async show(options: ShowToastOptions): Promise { + if (options.translateMessage && typeof options.message === 'string') { + options.message = Translate.instant(options.message); + } + + options.duration = options.duration ?? ToastDuration.SHORT; + + // Convert some values and set default values. + const toastOptions: ToastOptions = { + ...options, + duration: CoreConstants.CONFIG.toastDurations[options.duration] ?? options.duration ?? 2000, + position: options.position ?? 'bottom', + }; + + const loader = await ToastController.create(toastOptions); + + await loader.present(); + + fixOverlayAriaHidden(loader); + + return loader; + } + +} + +export const CoreToasts = makeSingleton(CoreToastsService); + +/** + * Toast duration. + */ +export enum ToastDuration { + LONG = 'long', + SHORT = 'short', + STICKY = 'sticky', +} + +/** + * Options for showToastWithOptions. + */ +export type ShowToastOptions = Omit & { + duration?: ToastDuration | number; + translateMessage?: boolean; +}; diff --git a/src/core/services/utils/dom.ts b/src/core/services/utils/dom.ts index c00e2f88d..5090f66c8 100644 --- a/src/core/services/utils/dom.ts +++ b/src/core/services/utils/dom.ts @@ -14,7 +14,7 @@ import { Injectable, SimpleChange, KeyValueChanges } from '@angular/core'; import { IonContent } from '@ionic/angular'; -import { ModalOptions, PopoverOptions, AlertOptions, AlertButton, TextFieldTypes, ToastOptions } from '@ionic/core'; +import { ModalOptions, PopoverOptions, AlertOptions, AlertButton, TextFieldTypes } from '@ionic/core'; import { Md5 } from 'ts-md5'; import { CoreConfig } from '@services/config'; @@ -32,12 +32,9 @@ import { makeSingleton, Translate, AlertController, - ToastController, PopoverController, ModalController, Router, - ActionSheetController, - LoadingController, } from '@singletons'; import { CoreLogger } from '@singletons/logger'; import { CoreFileSizeSum } from '@services/plugin-file-delegate'; @@ -60,6 +57,8 @@ import { CoreWSError } from '@classes/errors/wserror'; import { CoreErrorLogs } from '@singletons/error-logs'; import { CoreKeyboard } from '@singletons/keyboard'; import { CoreWait } from '@singletons/wait'; +import { CoreToasts, ToastDuration, ShowToastOptions } from '../toasts'; +import { fixOverlayAriaHidden } from '@/core/utils/fix-aria-hidden'; /* * "Utils" service with helper functions for UI, DOM elements and HTML code. @@ -874,7 +873,7 @@ export class CoreDomUtilsProvider { alertMessageEl && this.treatAnchors(alertMessageEl); } - this.fixAriaHidden(alert); + fixOverlayAriaHidden(alert); return; }); @@ -1375,27 +1374,26 @@ export class CoreDomUtilsProvider { /** * Displays an autodimissable toast modal window. * - * @param text The text of the toast. - * @param needsTranslate Whether the 'text' needs to be translated. + * @param message The text of the toast. + * @param translateMessage Whether the 'text' needs to be translated. * @param duration Duration in ms of the dimissable toast. * @param cssClass Class to add to the toast. * @returns Toast instance. + * + * @deprecated since 4.5. Use CoreToasts.show instead. */ async showToast( - text: string, - needsTranslate?: boolean, + message: string, + translateMessage?: boolean, duration: ToastDuration | number = ToastDuration.SHORT, cssClass: string = '', ): Promise { - if (needsTranslate) { - text = Translate.instant(text); - } - - return this.showToastWithOptions({ - message: text, - duration: duration, + return CoreToasts.show({ + message, + translateMessage, + duration, + cssClass, position: 'bottom', - cssClass: cssClass, }); } @@ -1404,22 +1402,11 @@ export class CoreDomUtilsProvider { * * @param options Options. * @returns Promise resolved with Toast instance. + * + * @deprecated since 4.5. Use CoreToasts.show instead. */ async showToastWithOptions(options: ShowToastOptions): Promise { - // Convert some values and set default values. - const toastOptions: ToastOptions = { - ...options, - duration: CoreConstants.CONFIG.toastDurations[options.duration] ?? options.duration ?? 2000, - position: options.position ?? 'bottom', - }; - - const loader = await ToastController.create(toastOptions); - - await loader.present(); - - this.fixAriaHidden(loader); - - return loader; + return CoreToasts.show(options); } /** @@ -1515,7 +1502,7 @@ export class CoreDomUtilsProvider { } if (!alreadyDisplayed) { - this.fixAriaHidden(modal); + fixOverlayAriaHidden(modal); } const result = await resultPromise; @@ -1528,32 +1515,6 @@ export class CoreDomUtilsProvider { } } - /** - * Temporary fix to remove aria-hidden from ion-router-outlet if needed. It can be removed once the Ionic bug is fixed. - * https://github.com/ionic-team/ionic-framework/issues/29396 - * - * @param overlay Overlay dismissed. - */ - protected async fixAriaHidden( - overlay: HTMLIonModalElement | HTMLIonPopoverElement | HTMLIonAlertElement | HTMLIonToastElement, - ): Promise { - - await overlay.onDidDismiss(); - - const overlays = await Promise.all([ - ModalController.getTop(), - PopoverController.getTop(), - ActionSheetController.getTop(), - AlertController.getTop(), - LoadingController.getTop(), - ToastController.getTop(), - ]); - - if (!overlays.find(overlay => overlay !== undefined)) { - document.querySelector('ion-router-outlet')?.removeAttribute('aria-hidden'); - } - } - /** * Opens a side Modal. * @@ -1603,7 +1564,7 @@ export class CoreDomUtilsProvider { await popover.present(); - this.fixAriaHidden(popover); + fixOverlayAriaHidden(popover); return popover; } @@ -1841,19 +1802,3 @@ export enum VerticalPoint { MID = 'mid', BOTTOM = 'bottom', } - -/** - * Toast duration. - */ -export enum ToastDuration { - LONG = 'long', - SHORT = 'short', - STICKY = 'sticky', -} - -/** - * Options for showToastWithOptions. - */ -export type ShowToastOptions = Omit & { - duration: ToastDuration | number; -}; diff --git a/src/core/singletons/text.ts b/src/core/singletons/text.ts index 100c9be74..19b15a8b8 100644 --- a/src/core/singletons/text.ts +++ b/src/core/singletons/text.ts @@ -13,7 +13,7 @@ // limitations under the License. import { Clipboard } from '@singletons'; -import { CoreDomUtils } from '@services/utils/dom'; +import { CoreToasts } from '@services/toasts'; /** * Singleton with helper functions for text manipulation. @@ -89,7 +89,10 @@ export class CoreText { } // Show toast using ionicLoading. - CoreDomUtils.showToast('core.copiedtoclipboard', true); + CoreToasts.show({ + message: 'core.copiedtoclipboard', + translateMessage: true, + }); } } diff --git a/src/core/utils/fix-aria-hidden.ts b/src/core/utils/fix-aria-hidden.ts new file mode 100644 index 000000000..68ef2f85b --- /dev/null +++ b/src/core/utils/fix-aria-hidden.ts @@ -0,0 +1,50 @@ +// (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 { + ActionSheetController, + AlertController, + LoadingController, + ModalController, + PopoverController, + ToastController, +} from '@singletons'; + +/** + * Temporary fix to remove aria-hidden from ion-router-outlet if needed. It can be removed once the Ionic bug is fixed. + * https://github.com/ionic-team/ionic-framework/issues/29396 + * + * !!! Only for internal use, this function will be removed without deprecation !!! + * + * @param overlay Overlay dismissed. + */ +export async function fixOverlayAriaHidden( + overlay: HTMLIonModalElement | HTMLIonPopoverElement | HTMLIonAlertElement | HTMLIonToastElement, +): Promise { + + await overlay.onDidDismiss(); + + const overlays = await Promise.all([ + ModalController.getTop(), + PopoverController.getTop(), + ActionSheetController.getTop(), + AlertController.getTop(), + LoadingController.getTop(), + ToastController.getTop(), + ]); + + if (!overlays.find(overlay => overlay !== undefined)) { + document.querySelector('ion-router-outlet')?.removeAttribute('aria-hidden'); + } +} diff --git a/src/types/config.d.ts b/src/types/config.d.ts index cda618cf6..e3de69599 100644 --- a/src/types/config.d.ts +++ b/src/types/config.d.ts @@ -18,7 +18,7 @@ import { CoreLoginSiteInfo, CoreSitesDemoSiteData } from '@services/sites'; import { OpenFileAction } from '@services/utils/utils'; import { CoreLoginSiteFinderSettings, CoreLoginSiteSelectorListMethod } from '@features/login/services/login-helper'; import { CoreDatabaseConfiguration } from '@classes/database/database-table'; -import { ToastDuration } from '@services/utils/dom'; +import { ToastDuration } from '@services/toasts'; /* eslint-disable @typescript-eslint/naming-convention */