diff --git a/moodle.config.json b/moodle.config.json index ab1c55d95..13f142090 100644 --- a/moodle.config.json +++ b/moodle.config.json @@ -104,5 +104,10 @@ }, "wsrequestqueuelimit": 10, "wsrequestqueuedelay": 100, - "calendarreminderdefaultvalue": 3600 + "calendarreminderdefaultvalue": 3600, + "toastDurations": { + "short": 2000, + "long": 3500, + "sticky": 0 + } } diff --git a/src/addons/calendar/pages/event/event.page.ts b/src/addons/calendar/pages/event/event.page.ts index ac9a3ac11..362c4332e 100644 --- a/src/addons/calendar/pages/event/event.page.ts +++ b/src/addons/calendar/pages/event/event.page.ts @@ -25,7 +25,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 } from '@services/utils/dom'; +import { CoreDomUtils, ToastDuration } from '@services/utils/dom'; import { CoreTextUtils } from '@services/utils/text'; import { CoreSites } from '@services/sites'; import { CoreLocalNotifications } from '@services/local-notifications'; @@ -556,7 +556,7 @@ export class AddonCalendarEventPage implements OnInit, OnDestroy { } if (onlineEventDeleted || this.event.id < 0) { - CoreDomUtils.showToast('addon.calendar.eventcalendareventdeleted', true, 3000); + CoreDomUtils.showToast('addon.calendar.eventcalendareventdeleted', true, ToastDuration.LONG); // Event deleted, close the view. CoreNavigator.back(); @@ -611,7 +611,7 @@ export class AddonCalendarEventPage implements OnInit, OnDestroy { } if (data.deleted && data.deleted.indexOf(this.eventId) != -1) { - CoreDomUtils.showToast('addon.calendar.eventcalendareventdeleted', true, 3000); + CoreDomUtils.showToast('addon.calendar.eventcalendareventdeleted', true, 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 a1a29932e..8cc7d519a 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 } from '@services/utils/dom'; +import { CoreDomUtils, ToastDuration } from '@services/utils/dom'; import { CoreFormFields, CoreForms } from '@singletons/form'; import { Translate } from '@singletons'; import { CoreEvents } from '@singletons/events'; @@ -467,7 +467,7 @@ export class AddonModAssignEditPage implements OnInit, OnDestroy, CanLeave { async timeUp(): Promise { this.timeUpToast = await CoreDomUtils.showToastWithOptions({ message: Translate.instant('addon.mod_assign.caneditsubmission'), - duration: 0, + duration: ToastDuration.STICKY, buttons: [Translate.instant('core.dismiss')], cssClass: 'core-danger-toast', }); diff --git a/src/addons/mod/data/services/data-helper.ts b/src/addons/mod/data/services/data-helper.ts index e11bc25d9..6993f0210 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 '@ionic-native/file/ngx'; import { CoreSites, CoreSitesReadingStrategy } from '@services/sites'; -import { CoreDomUtils } from '@services/utils/dom'; +import { CoreDomUtils, ToastDuration } from '@services/utils/dom'; import { CoreFormFields } from '@singletons/form'; import { CoreTextUtils } from '@services/utils/text'; import { CoreUtils } from '@services/utils/utils'; @@ -173,7 +173,11 @@ export class AddonModDataHelperProvider { CoreEvents.trigger(AddonModDataProvider.ENTRY_CHANGED, { dataId: dataId, entryId: entryId }, siteId); - CoreDomUtils.showToast(approve ? 'addon.mod_data.recordapproved' : 'addon.mod_data.recorddisapproved', true, 3000); + CoreDomUtils.showToast( + approve ? 'addon.mod_data.recordapproved' : 'addon.mod_data.recorddisapproved', + true, + ToastDuration.LONG, + ); } catch { // Ignore error, it was already displayed. } finally { @@ -725,7 +729,7 @@ export class AddonModDataHelperProvider { CoreEvents.trigger(AddonModDataProvider.ENTRY_CHANGED, { dataId, entryId, deleted: true }, siteId); - CoreDomUtils.showToast('addon.mod_data.recorddeleted', true, 3000); + CoreDomUtils.showToast('addon.mod_data.recorddeleted', true, ToastDuration.LONG); modal.dismiss(); } catch { diff --git a/src/addons/notes/components/add/add-modal.ts b/src/addons/notes/components/add/add-modal.ts index 46b38c524..ae840fd41 100644 --- a/src/addons/notes/components/add/add-modal.ts +++ b/src/addons/notes/components/add/add-modal.ts @@ -16,7 +16,7 @@ import { AddonNotes, AddonNotesPublishState } from '@addons/notes/services/notes import { Component, ViewChild, ElementRef, Input } from '@angular/core'; import { CoreApp } from '@services/app'; import { CoreSites } from '@services/sites'; -import { CoreDomUtils } from '@services/utils/dom'; +import { CoreDomUtils, ToastDuration } from '@services/utils/dom'; import { CoreForms } from '@singletons/form'; import { ModalController } from '@singletons'; @@ -57,7 +57,7 @@ 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, 3000); + CoreDomUtils.showToast(sent ? 'addon.notes.eventnotecreated' : 'core.datastoredoffline', true, ToastDuration.LONG); }); } catch (error){ CoreDomUtils.showErrorModal(error); diff --git a/src/addons/notes/pages/list/list.page.ts b/src/addons/notes/pages/list/list.page.ts index 64c0a373d..8f5547af5 100644 --- a/src/addons/notes/pages/list/list.page.ts +++ b/src/addons/notes/pages/list/list.page.ts @@ -23,7 +23,7 @@ import { CoreUser, CoreUserProfile } from '@features/user/services/user'; import { IonContent, IonRefresher } from '@ionic/angular'; import { CoreNavigator } from '@services/navigator'; import { CoreSites } from '@services/sites'; -import { CoreDomUtils } from '@services/utils/dom'; +import { CoreDomUtils, ToastDuration } from '@services/utils/dom'; import { CoreTextUtils } from '@services/utils/text'; import { CoreUtils } from '@services/utils/utils'; import { CoreEventObserver, CoreEvents } from '@singletons/events'; @@ -232,7 +232,7 @@ export class AddonNotesListPage implements OnInit, OnDestroy { this.refreshNotes(false); - CoreDomUtils.showToast('addon.notes.eventnotedeleted', true, 3000); + CoreDomUtils.showToast('addon.notes.eventnotedeleted', true, ToastDuration.LONG); } catch (error) { CoreDomUtils.showErrorModalDefault(error, 'Delete note failed.'); diff --git a/src/core/classes/site.ts b/src/core/classes/site.ts index 58c994959..5fcd79060 100644 --- a/src/core/classes/site.ts +++ b/src/core/classes/site.ts @@ -29,7 +29,7 @@ import { CoreWSUploadFileResult, CoreWSPreSetsSplitRequest, } from '@services/ws'; -import { CoreDomUtils } from '@services/utils/dom'; +import { CoreDomUtils, ToastDuration } from '@services/utils/dom'; import { CoreTextUtils } from '@services/utils/text'; import { CoreTimeUtils } from '@services/utils/time'; import { CoreUrlUtils, CoreUrlParams } from '@services/utils/url'; @@ -572,7 +572,7 @@ export class CoreSite { if (wsPreSets.cleanUnicode && CoreTextUtils.hasUnicodeData(data)) { // Data will be cleaned, notify the user. - CoreDomUtils.showToast('core.unicodenotsupported', true, 3000); + CoreDomUtils.showToast('core.unicodenotsupported', true, ToastDuration.LONG); } else { // No need to clean data in this call. wsPreSets.cleanUnicode = false; diff --git a/src/core/features/comments/pages/viewer/viewer.page.ts b/src/core/features/comments/pages/viewer/viewer.page.ts index 4b79eedfe..32084a2ac 100644 --- a/src/core/features/comments/pages/viewer/viewer.page.ts +++ b/src/core/features/comments/pages/viewer/viewer.page.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 } from '@services/utils/dom'; +import { CoreDomUtils, ToastDuration } from '@services/utils/dom'; import { CoreUser } from '@features/user/services/user'; import { CoreTextUtils } from '@services/utils/text'; import { CoreError } from '@classes/errors/error'; @@ -319,7 +319,7 @@ export class CoreCommentsViewerPage implements OnInit, OnDestroy { CoreDomUtils.showToast( commentsResponse ? 'core.comments.eventcommentcreated' : 'core.datastoredoffline', true, - 3000, + ToastDuration.LONG, ); if (commentsResponse) { @@ -417,7 +417,7 @@ export class CoreCommentsViewerPage implements OnInit, OnDestroy { this.invalidateComments(); - CoreDomUtils.showToast('core.comments.eventcommentdeleted', true, 3000); + CoreDomUtils.showToast('core.comments.eventcommentdeleted', true, ToastDuration.LONG); } catch (error) { CoreDomUtils.showErrorModalDefault(error, 'Delete comment failed.'); } diff --git a/src/core/features/rating/components/rate/rate.ts b/src/core/features/rating/components/rate/rate.ts index cf2c43639..fd87f9dd0 100644 --- a/src/core/features/rating/components/rate/rate.ts +++ b/src/core/features/rating/components/rate/rate.ts @@ -23,7 +23,7 @@ import { } from '@features/rating/services/rating'; import { CoreRatingOffline } from '@features/rating/services/rating-offline'; import { CoreSites } from '@services/sites'; -import { CoreDomUtils } from '@services/utils/dom'; +import { CoreDomUtils, ToastDuration } from '@services/utils/dom'; import { Translate } from '@singletons'; import { CoreEventObserver, CoreEvents } from '@singletons/events'; @@ -143,7 +143,7 @@ export class CoreRatingRateComponent implements OnChanges, OnDestroy { ); if (response === undefined) { - CoreDomUtils.showToast('core.datastoredoffline', true, 3000); + CoreDomUtils.showToast('core.datastoredoffline', true, ToastDuration.LONG); } else { this.onUpdate.emit(); } diff --git a/src/core/services/utils/dom.ts b/src/core/services/utils/dom.ts index 7861e147a..70cd4c47a 100644 --- a/src/core/services/utils/dom.ts +++ b/src/core/services/utils/dom.ts @@ -1614,23 +1614,19 @@ export class CoreDomUtilsProvider { async showToast( text: string, needsTranslate?: boolean, - duration: number = 2000, + duration: ToastDuration | number = ToastDuration.SHORT, cssClass: string = '', ): Promise { if (needsTranslate) { text = Translate.instant(text); } - const loader = await ToastController.create({ + return this.showToastWithOptions({ message: text, duration: duration, position: 'bottom', cssClass: cssClass, }); - - await loader.present(); - - return loader; } /** @@ -1639,12 +1635,15 @@ export class CoreDomUtilsProvider { * @param options Options. * @return Promise resolved with Toast instance. */ - async showToastWithOptions(options: ToastOptions): Promise { - // Set some default values. - options.duration = options.duration ?? 2000; - options.position = options.position ?? 'bottom'; + 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(options); + const loader = await ToastController.create(toastOptions); await loader.present(); @@ -2130,3 +2129,19 @@ 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/types/config.d.ts b/src/types/config.d.ts index 75c1e84f3..571e3ecd3 100644 --- a/src/types/config.d.ts +++ b/src/types/config.d.ts @@ -18,6 +18,7 @@ import { CoreSitesDemoSiteData } from '@services/sites'; import { OpenFileAction } from '@services/utils/utils'; import { CoreLoginSiteSelectorListMethod } from '@features/login/services/login-helper'; import { CoreDatabaseConfiguration } from '@classes/database/database-table'; +import { ToastDuration } from '@services/utils/dom'; /* eslint-disable @typescript-eslint/naming-convention */ @@ -69,4 +70,5 @@ export interface EnvironmentConfig { calendarreminderdefaultvalue: number; // Initial value for default reminders (in seconds). User can change it later. removeaccountonlogout?: boolean; // True to remove the account when the user clicks logout. Doesn't affect switch account. uselegacycompletion?: boolean; // Whether to use legacy completion by default in all course formats. + toastDurations: Record; }