diff --git a/src/addons/calendar/components/components.module.ts b/src/addons/calendar/components/components.module.ts index 68b2bdee2..fffd48aa8 100644 --- a/src/addons/calendar/components/components.module.ts +++ b/src/addons/calendar/components/components.module.ts @@ -19,25 +19,20 @@ import { CoreSharedModule } from '@/core/shared.module'; import { AddonCalendarCalendarComponent } from './calendar/calendar'; import { AddonCalendarUpcomingEventsComponent } from './upcoming-events/upcoming-events'; import { AddonCalendarFilterComponent } from './filter/filter'; -import { AddonCalendarReminderTimeModalComponent } from './reminder-time-modal/reminder-time-modal'; @NgModule({ declarations: [ AddonCalendarCalendarComponent, AddonCalendarUpcomingEventsComponent, AddonCalendarFilterComponent, - AddonCalendarReminderTimeModalComponent, ], imports: [ CoreSharedModule, ], - providers: [ - ], exports: [ AddonCalendarCalendarComponent, AddonCalendarUpcomingEventsComponent, AddonCalendarFilterComponent, - AddonCalendarReminderTimeModalComponent, ], }) export class AddonCalendarComponentsModule {} diff --git a/src/addons/calendar/components/reminder-time-modal/reminder-time-modal.html b/src/addons/calendar/components/reminder-time-modal/reminder-time-modal.html deleted file mode 100644 index 1071b92d9..000000000 --- a/src/addons/calendar/components/reminder-time-modal/reminder-time-modal.html +++ /dev/null @@ -1,62 +0,0 @@ - - - -

{{ 'addon.calendar.reminders' | translate }}

-
- - - - - -
-
- -
- - - - -

{{ 'core.settings.disabled' | translate }}

-
- -
- - -

{{ option.label }}

-
- -
- - - - -

{{ 'core.custom' | translate }}

-
- -
- - - -
- - - - - - - - - {{ option.label | translate }} - - -
-
-
- - - {{ 'core.done' | translate }} - -
-
diff --git a/src/addons/calendar/components/reminder-time-modal/reminder-time-modal.ts b/src/addons/calendar/components/reminder-time-modal/reminder-time-modal.ts deleted file mode 100644 index 1a10a9c27..000000000 --- a/src/addons/calendar/components/reminder-time-modal/reminder-time-modal.ts +++ /dev/null @@ -1,174 +0,0 @@ -// (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 { AddonCalendar, AddonCalendarReminderUnits, AddonCalendarValueAndUnit } from '@addons/calendar/services/calendar'; -import { Component, Input, OnInit } from '@angular/core'; -import { CoreDomUtils } from '@services/utils/dom'; -import { ModalController } from '@singletons'; - -/** - * Modal to choose a reminder time. - */ -@Component({ - selector: 'addon-calendar-new-reminder-modal', - templateUrl: 'reminder-time-modal.html', -}) -export class AddonCalendarReminderTimeModalComponent implements OnInit { - - @Input() initialValue?: AddonCalendarValueAndUnit; - @Input() allowDisable?: boolean; - - radioValue = '5m'; - customValue = '10'; - customUnits = AddonCalendarReminderUnits.MINUTE; - - presetOptions = [ - { - radioValue: '5m', - value: 5, - unit: AddonCalendarReminderUnits.MINUTE, - label: '', - }, - { - radioValue: '10m', - value: 10, - unit: AddonCalendarReminderUnits.MINUTE, - label: '', - }, - { - radioValue: '30m', - value: 30, - unit: AddonCalendarReminderUnits.MINUTE, - label: '', - }, - { - radioValue: '1h', - value: 1, - unit: AddonCalendarReminderUnits.HOUR, - label: '', - }, - { - radioValue: '12h', - value: 12, - unit: AddonCalendarReminderUnits.HOUR, - label: '', - }, - { - radioValue: '1d', - value: 1, - unit: AddonCalendarReminderUnits.DAY, - label: '', - }, - ]; - - customUnitsOptions = [ - { - value: AddonCalendarReminderUnits.MINUTE, - label: 'core.minutes', - }, - { - value: AddonCalendarReminderUnits.HOUR, - label: 'core.hours', - }, - { - value: AddonCalendarReminderUnits.DAY, - label: 'core.days', - }, - { - value: AddonCalendarReminderUnits.WEEK, - label: 'core.weeks', - }, - ]; - - /** - * @inheritdoc - */ - async ngOnInit(): Promise { - this.presetOptions.forEach((option) => { - option.label = AddonCalendar.getUnitValueLabel(option.value, option.unit); - }); - - if (!this.initialValue) { - return; - } - - if (this.initialValue.value === 0) { - this.radioValue = 'disabled'; - } else { - // Search if it's one of the preset options. - const option = this.presetOptions.find(option => - option.value === this.initialValue?.value && option.unit === this.initialValue.unit); - - if (option) { - this.radioValue = option.radioValue; - } else { - // It's a custom value. - this.radioValue = 'custom'; - this.customValue = String(this.initialValue.value); - this.customUnits = this.initialValue.unit; - } - } - } - - /** - * Close the modal. - */ - closeModal(): void { - ModalController.dismiss(); - } - - /** - * Save the reminder. - */ - saveReminder(): void { - if (this.radioValue === 'disabled') { - ModalController.dismiss(0); - } else if (this.radioValue === 'custom') { - const value = parseInt(this.customValue, 10); - if (!value) { - CoreDomUtils.showErrorModal('core.errorinvalidform', true); - - return; - } - - ModalController.dismiss(Math.abs(value) * this.customUnits); - } else { - const option = this.presetOptions.find(option => option.radioValue === this.radioValue); - if (!option) { - return; - } - - ModalController.dismiss(option.unit * option.value); - } - } - - /** - * Custom value input clicked. - * - * @param ev Click event. - */ - async customInputClicked(ev: Event): Promise { - if (this.radioValue === 'custom') { - return; - } - - this.radioValue = 'custom'; - - const target = ev.target; - if (target) { - CoreDomUtils.focusElement(target); - } - } - -} diff --git a/src/addons/calendar/lang.json b/src/addons/calendar/lang.json index a71e8921b..c448ad2db 100644 --- a/src/addons/calendar/lang.json +++ b/src/addons/calendar/lang.json @@ -41,7 +41,6 @@ "noevents": "There are no events", "nopermissiontoupdatecalendar": "Sorry, but you do not have permission to update the calendar event.", "reminders": "Reminders", - "units": "Units", "repeatedevents": "Repeated events", "repeateditall": "Also apply changes to the other {{$a}} events in this repeat series", "repeateditthis": "Apply changes to this event only", @@ -55,7 +54,6 @@ "sunday": "Sunday", "thu": "Thu", "thursday": "Thursday", - "timebefore": "{{value}} {{units}} before", "today": "Today", "tomorrow": "Tomorrow", "tue": "Tue", diff --git a/src/addons/calendar/pages/edit-event/edit-event.page.ts b/src/addons/calendar/pages/edit-event/edit-event.page.ts index 78087afcc..e01ca933d 100644 --- a/src/addons/calendar/pages/edit-event/edit-event.page.ts +++ b/src/addons/calendar/pages/edit-event/edit-event.page.ts @@ -31,7 +31,6 @@ import { AddonCalendarEventType, AddonCalendar, AddonCalendarSubmitCreateUpdateFormDataWSParams, - AddonCalendarReminderUnits, } from '../../services/calendar'; import { AddonCalendarOffline } from '../../services/calendar-offline'; import { AddonCalendarEventTypeOption, AddonCalendarHelper } from '../../services/calendar-helper'; @@ -45,7 +44,8 @@ import { CoreNavigator } from '@services/navigator'; import { CanLeave } from '@guards/can-leave'; import { CoreForms } from '@singletons/form'; import { CoreLocalNotifications } from '@services/local-notifications'; -import { AddonCalendarReminderTimeModalComponent } from '@addons/calendar/components/reminder-time-modal/reminder-time-modal'; +import { CoreReminders, CoreRemindersService, CoreRemindersUnits } from '@features/reminders/services/reminders'; +import { CoreRemindersSetReminderMenuComponent } from '@features/reminders/components/set-reminder-menu/set-reminder-menu'; /** * Page that displays a form to create/edit an event. @@ -134,7 +134,7 @@ export class AddonCalendarEditEventPage implements OnInit, OnDestroy, CanLeave { } /** - * Component being initialized. + * @inheritdoc */ ngOnInit(): void { this.eventId = CoreNavigator.getRouteNumberParam('eventId') || undefined; @@ -657,13 +657,13 @@ export class AddonCalendarEditEventPage implements OnInit, OnDestroy, CanLeave { return; } - const data = AddonCalendarProvider.convertSecondsToValueAndUnit(defaultTime); + const data = CoreRemindersService.convertSecondsToValueAndUnit(defaultTime); // Add default reminder. this.reminders.push({ value: data.value, unit: data.unit, - label: AddonCalendar.getUnitValueLabel(data.value, data.unit, true), + label: CoreReminders.getUnitValueLabel(data.value, data.unit, true), }); } @@ -671,8 +671,9 @@ export class AddonCalendarEditEventPage implements OnInit, OnDestroy, CanLeave { * Add a reminder. */ async addReminder(): Promise { - const reminderTime = await CoreDomUtils.openModal({ - component: AddonCalendarReminderTimeModalComponent, + const reminderTime = await CoreDomUtils.openPopover<{timeBefore: number}>({ + component: CoreRemindersSetReminderMenuComponent, + // TODO: Add event to open the popover in place. }); if (reminderTime === undefined) { @@ -680,14 +681,14 @@ export class AddonCalendarEditEventPage implements OnInit, OnDestroy, CanLeave { return; } - const data = AddonCalendarProvider.convertSecondsToValueAndUnit(reminderTime); + const data = CoreRemindersService.convertSecondsToValueAndUnit(reminderTime.timeBefore); // Add reminder. this.reminders.push({ - time: reminderTime, + time: reminderTime.timeBefore, value: data.value, unit: data.unit, - label: AddonCalendar.getUnitValueLabel(data.value, data.unit), + label: CoreReminders.getUnitValueLabel(data.value, data.unit), }); } @@ -704,7 +705,7 @@ export class AddonCalendarEditEventPage implements OnInit, OnDestroy, CanLeave { } /** - * Page destroyed. + * @inheritdoc */ ngOnDestroy(): void { this.unblockSync(); @@ -716,6 +717,6 @@ export class AddonCalendarEditEventPage implements OnInit, OnDestroy, CanLeave { type AddonCalendarEventCandidateReminder = { time?: number; // Undefined for default reminder. value: number; // Amount of time. - unit: AddonCalendarReminderUnits; // Units. + unit: CoreRemindersUnits; // Units. label: string; // Label to represent the reminder. }; diff --git a/src/addons/calendar/pages/event/event.page.ts b/src/addons/calendar/pages/event/event.page.ts index 19fe931c1..6f0e3bd32 100644 --- a/src/addons/calendar/pages/event/event.page.ts +++ b/src/addons/calendar/pages/event/event.page.ts @@ -38,11 +38,11 @@ import { CoreNavigator } from '@services/navigator'; import { CoreUtils } from '@services/utils/utils'; import { ActivatedRoute, ActivatedRouteSnapshot } from '@angular/router'; import { CoreConstants } from '@/core/constants'; -import { AddonCalendarReminderTimeModalComponent } from '@addons/calendar/components/reminder-time-modal/reminder-time-modal'; import { CoreRoutedItemsManagerSourcesTracker } from '@classes/items-management/routed-items-manager-sources-tracker'; import { AddonCalendarEventsSource } from '@addons/calendar/classes/events-source'; import { CoreSwipeNavigationItemsManager } from '@classes/items-management/swipe-navigation-items-manager'; import { CoreReminders } from '@features/reminders/services/reminders'; +import { CoreRemindersSetReminderMenuComponent } from '@features/reminders/components/set-reminder-menu/set-reminder-menu'; /** * Page that displays a single calendar event. @@ -157,7 +157,7 @@ export class AddonCalendarEventPage implements OnInit, OnDestroy { } /** - * View loaded. + * @inheritdoc */ async ngOnInit(): Promise { try { @@ -387,8 +387,9 @@ export class AddonCalendarEventPage implements OnInit, OnDestroy { return; } - const reminderTime = await CoreDomUtils.openModal({ - component: AddonCalendarReminderTimeModalComponent, + const reminderTime = await CoreDomUtils.openPopover<{timeBefore: number}>({ + component: CoreRemindersSetReminderMenuComponent, + // TODO: Add event to open the popover in place. }); if (reminderTime === undefined) { @@ -396,7 +397,7 @@ export class AddonCalendarEventPage implements OnInit, OnDestroy { return; } - await AddonCalendar.addEventReminder(this.event, reminderTime, this.currentSiteId); + await AddonCalendar.addEventReminder(this.event, reminderTime.timeBefore, this.currentSiteId); await this.loadReminders(); } @@ -636,7 +637,7 @@ export class AddonCalendarEventPage implements OnInit, OnDestroy { } /** - * Page destroyed. + * @inheritdoc */ ngOnDestroy(): void { this.editEventObserver.off(); diff --git a/src/addons/calendar/pages/settings/settings.ts b/src/addons/calendar/pages/settings/settings.ts index ec1ee3455..743a54c7e 100644 --- a/src/addons/calendar/pages/settings/settings.ts +++ b/src/addons/calendar/pages/settings/settings.ts @@ -16,13 +16,17 @@ import { Component, OnInit } from '@angular/core'; import { AddonCalendar, AddonCalendarProvider, - AddonCalendarReminderUnits, - AddonCalendarValueAndUnit, } from '../../services/calendar'; import { CoreEvents } from '@singletons/events'; import { CoreSites } from '@services/sites'; import { CoreDomUtils } from '@services/utils/dom'; -import { AddonCalendarReminderTimeModalComponent } from '@addons/calendar/components/reminder-time-modal/reminder-time-modal'; +import { + CoreReminders, + CoreRemindersService, + CoreRemindersUnits, + CoreReminderValueAndUnit, +} from '@features/reminders/services/reminders'; +import { CoreRemindersSetReminderMenuComponent } from '@features/reminders/components/set-reminder-menu/set-reminder-menu'; /** * Page that displays the calendar settings. @@ -35,19 +39,16 @@ export class AddonCalendarSettingsPage implements OnInit { defaultTimeLabel = ''; - protected defaultTime: AddonCalendarValueAndUnit = { + protected defaultTime: CoreReminderValueAndUnit = { value: 0, - unit: AddonCalendarReminderUnits.MINUTE, + unit: CoreRemindersUnits.MINUTE, }; /** - * View loaded. + * @inheritdoc */ async ngOnInit(): Promise { - const defaultTime = await AddonCalendar.getDefaultNotificationTime(); - - this.defaultTime = AddonCalendarProvider.convertSecondsToValueAndUnit(defaultTime); - this.defaultTimeLabel = AddonCalendar.getUnitValueLabel(this.defaultTime.value, this.defaultTime.unit); + this.updateDefaultTimeLabel(); } /** @@ -61,12 +62,13 @@ export class AddonCalendarSettingsPage implements OnInit { e.stopImmediatePropagation(); e.preventDefault(); - const reminderTime = await CoreDomUtils.openModal({ - component: AddonCalendarReminderTimeModalComponent, + const reminderTime = await CoreDomUtils.openPopover<{timeBefore: number}>({ + component: CoreRemindersSetReminderMenuComponent, componentProps: { initialValue: this.defaultTime, - allowDisable: true, + noReminderLabel: 'core.settings.disabled', }, + event: e, }); if (reminderTime === undefined) { @@ -74,25 +76,24 @@ export class AddonCalendarSettingsPage implements OnInit { return; } - this.defaultTime = AddonCalendarProvider.convertSecondsToValueAndUnit(reminderTime); - this.defaultTimeLabel = AddonCalendar.getUnitValueLabel(this.defaultTime.value, this.defaultTime.unit); - - this.updateDefaultTime(reminderTime); - } - - /** - * Update default time. - * - * @param newTime New time. - */ - updateDefaultTime(newTime: number): void { - AddonCalendar.setDefaultNotificationTime(newTime); + await AddonCalendar.setDefaultNotificationTime(reminderTime.timeBefore); + this.updateDefaultTimeLabel(); CoreEvents.trigger( AddonCalendarProvider.DEFAULT_NOTIFICATION_TIME_CHANGED, - { time: newTime }, + { time: reminderTime.timeBefore }, CoreSites.getCurrentSiteId(), ); } + /** + * Update default time label. + */ + async updateDefaultTimeLabel(): Promise { + const defaultTime = await AddonCalendar.getDefaultNotificationTime(); + + this.defaultTime = CoreRemindersService.convertSecondsToValueAndUnit(defaultTime); + this.defaultTimeLabel = CoreReminders.getUnitValueLabel(this.defaultTime.value, this.defaultTime.unit); + } + } diff --git a/src/addons/calendar/services/calendar-helper.ts b/src/addons/calendar/services/calendar-helper.ts index 8ab7902b9..dfccc8588 100644 --- a/src/addons/calendar/services/calendar-helper.ts +++ b/src/addons/calendar/services/calendar-helper.ts @@ -337,8 +337,8 @@ export class AddonCalendarHelperProvider { let defaultLabel: string | undefined; if (defaultTime > AddonCalendarProvider.DEFAULT_NOTIFICATION_DISABLED) { - const data = AddonCalendarProvider.convertSecondsToValueAndUnit(defaultTime); - defaultLabel = AddonCalendar.getUnitValueLabel(data.value, data.unit, true); + const data = CoreRemindersService.convertSecondsToValueAndUnit(defaultTime); + defaultLabel = CoreReminders.getUnitValueLabel(data.value, data.unit, true); } return reminders.map((reminder) => { @@ -353,8 +353,8 @@ export class AddonCalendarHelperProvider { formatted.timestamp = eventTimestart - defaultTime; } } else { - const data = AddonCalendarProvider.convertSecondsToValueAndUnit(reminder.timebefore); - formatted.label = AddonCalendar.getUnitValueLabel(data.value, data.unit, false); + const data = CoreRemindersService.convertSecondsToValueAndUnit(reminder.timebefore); + formatted.label = CoreReminders.getUnitValueLabel(data.value, data.unit, false); formatted.timestamp = eventTimestart - reminder.timebefore; } diff --git a/src/addons/calendar/services/calendar.ts b/src/addons/calendar/services/calendar.ts index ebe961573..373d054b4 100644 --- a/src/addons/calendar/services/calendar.ts +++ b/src/addons/calendar/services/calendar.ts @@ -46,6 +46,8 @@ import { CoreReminders, CoreRemindersPushNotificationData, CoreRemindersService, + CoreRemindersUnits, + CoreReminderValueAndUnit, } from '@features/reminders/services/reminders'; import { CoreReminderDBRecord } from '@features/reminders/services/database/reminders'; @@ -64,6 +66,8 @@ export enum AddonCalendarEventType { /** * Units to set a reminder. + * + * @deprecated since 4.1 Use CoreReminderUnits instead. */ export enum AddonCalendarReminderUnits { MINUTE = CoreConstants.SECONDS_MINUTE, @@ -91,21 +95,6 @@ declare module '@singletons/events' { } -const REMINDER_UNITS_LABELS = { - single: { - [AddonCalendarReminderUnits.MINUTE]: 'core.minute', - [AddonCalendarReminderUnits.HOUR]: 'core.hour', - [AddonCalendarReminderUnits.DAY]: 'core.day', - [AddonCalendarReminderUnits.WEEK]: 'core.week', - }, - multi: { - [AddonCalendarReminderUnits.MINUTE]: 'core.minutes', - [AddonCalendarReminderUnits.HOUR]: 'core.hours', - [AddonCalendarReminderUnits.DAY]: 'core.days', - [AddonCalendarReminderUnits.WEEK]: 'core.weeks', - }, -}; - /** * Service to handle calendar events. */ @@ -127,7 +116,7 @@ export class AddonCalendarProvider { static readonly CALENDAR_TF_24 = '%H:%M'; // Calendar time in 24 hours format. static readonly CALENDAR_TF_12 = '%I:%M %p'; // Calendar time in 12 hours format. - static readonly DEFAULT_NOTIFICATION_DISABLED = 0; + static readonly DEFAULT_NOTIFICATION_DISABLED = -1; protected weekDays: AddonCalendarWeekDaysTranslationKeys[] = [ { @@ -196,34 +185,10 @@ export class AddonCalendarProvider { * * @param seconds Number of seconds. * @return Value and unit. + * @deprecated since 4.1 Use CoreRemindersService.convertSecondsToValueAndUnit instead. */ - static convertSecondsToValueAndUnit(seconds: number): AddonCalendarValueAndUnit { - if (seconds <= 0) { - return { - value: 0, - unit: AddonCalendarReminderUnits.MINUTE, - }; - } else if (seconds % AddonCalendarReminderUnits.WEEK === 0) { - return { - value: seconds / AddonCalendarReminderUnits.WEEK, - unit: AddonCalendarReminderUnits.WEEK, - }; - } else if (seconds % AddonCalendarReminderUnits.DAY === 0) { - return { - value: seconds / AddonCalendarReminderUnits.DAY, - unit: AddonCalendarReminderUnits.DAY, - }; - } else if (seconds % AddonCalendarReminderUnits.HOUR === 0) { - return { - value: seconds / AddonCalendarReminderUnits.HOUR, - unit: AddonCalendarReminderUnits.HOUR, - }; - } else { - return { - value: seconds / AddonCalendarReminderUnits.MINUTE, - unit: AddonCalendarReminderUnits.MINUTE, - }; - } + static convertSecondsToValueAndUnit(seconds: number): CoreReminderValueAndUnit { + return CoreRemindersService.convertSecondsToValueAndUnit(seconds); } /** @@ -1140,26 +1105,10 @@ export class AddonCalendarProvider { * @param unit Unit. * @param addDefaultLabel Whether to add the "Default" text. * @return Translated label. + * @deprecated since 4.1 Use CoreReminders.getUnitValueLabel instead. */ - getUnitValueLabel(value: number, unit: AddonCalendarReminderUnits, addDefaultLabel = false): string { - if (value === 0) { - return Translate.instant('core.settings.disabled'); - } - - const unitsLabel = value === 1 ? - REMINDER_UNITS_LABELS.single[unit] : - REMINDER_UNITS_LABELS.multi[unit]; - - const label = Translate.instant('addon.calendar.timebefore', { - units: Translate.instant(unitsLabel), - value: value, - }); - - if (addDefaultLabel) { - return Translate.instant('core.defaultvalue', { $a: label }); - } - - return label; + getUnitValueLabel(value: number, unit: CoreRemindersUnits, addDefaultLabel = false): string { + return CoreReminders.getUnitValueLabel(value, unit, addDefaultLabel); } /** @@ -2318,11 +2267,10 @@ export type AddonCalendarUpdatedEventEvent = { /** * Value and unit for reminders. + * + * @deprecated since 4.1, use CoreReminderValueAndUnit instead. */ -export type AddonCalendarValueAndUnit = { - value: number; - unit: AddonCalendarReminderUnits; -}; +export type AddonCalendarValueAndUnit = CoreReminderValueAndUnit; /** * Options to pass to submit event. diff --git a/src/core/features/contentlinks/services/contentlinks-helper.ts b/src/core/features/contentlinks/services/contentlinks-helper.ts index e4d6379dd..a62abffb3 100644 --- a/src/core/features/contentlinks/services/contentlinks-helper.ts +++ b/src/core/features/contentlinks/services/contentlinks-helper.ts @@ -98,7 +98,6 @@ export class CoreContentLinksHelperProvider { * @param pageName Name of the page to go. * @param pageParams Params to send to the page. * @param siteId Site ID. If not defined, current site. - * @param checkMenu If true, check if the root page of a main menu tab. Only the page name will be checked. * @return Promise resolved when done. * @deprecated since 3.9.5. Use CoreNavigator.navigateToSitePath instead. */ diff --git a/src/core/features/reminders/components/components.module.ts b/src/core/features/reminders/components/components.module.ts new file mode 100644 index 000000000..a16051728 --- /dev/null +++ b/src/core/features/reminders/components/components.module.ts @@ -0,0 +1,33 @@ +// (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 { CoreSharedModule } from '@/core/shared.module'; +import { NgModule } from '@angular/core'; +import { CoreRemindersSetReminderCustomComponent } from './set-reminder-custom/set-reminder-custom'; +import { CoreRemindersSetReminderMenuComponent } from './set-reminder-menu/set-reminder-menu'; + +@NgModule({ + declarations: [ + CoreRemindersSetReminderMenuComponent, + CoreRemindersSetReminderCustomComponent, + ], + imports: [ + CoreSharedModule, + ], + exports: [ + CoreRemindersSetReminderMenuComponent, + CoreRemindersSetReminderCustomComponent, + ], +}) +export class CoreRemindersComponentsModule {} diff --git a/src/core/features/reminders/components/set-reminder-custom/set-reminder-custom.html b/src/core/features/reminders/components/set-reminder-custom/set-reminder-custom.html new file mode 100644 index 000000000..963338033 --- /dev/null +++ b/src/core/features/reminders/components/set-reminder-custom/set-reminder-custom.html @@ -0,0 +1,37 @@ + + + +

{{ 'core.reminders.customreminder' | translate }}

+
+
+
+ + +
+ + + + + + + + + {{ option.label | translate }} + + +
+
+ + + + {{ 'core.cancel' | translate }} + + + + {{ 'core.done' | translate }} + + + + +
diff --git a/src/core/features/reminders/components/set-reminder-custom/set-reminder-custom.ts b/src/core/features/reminders/components/set-reminder-custom/set-reminder-custom.ts new file mode 100644 index 000000000..617309627 --- /dev/null +++ b/src/core/features/reminders/components/set-reminder-custom/set-reminder-custom.ts @@ -0,0 +1,64 @@ +// (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 { Component, Input } from '@angular/core'; +import { CoreRemindersUnits } from '@features/reminders/services/reminders'; +import { PopoverController } from '@singletons'; + +/** + * This component is meant to set a custom reminder + */ +@Component({ + templateUrl: 'set-reminder-custom.html', +}) +export class CoreRemindersSetReminderCustomComponent { + + @Input() customValue = 10; + @Input() customUnits = CoreRemindersUnits.MINUTE; + + customUnitsOptions = [ + { + value: CoreRemindersUnits.MINUTE, + label: 'core.minutes', + }, + { + value: CoreRemindersUnits.HOUR, + label: 'core.hours', + }, + { + value: CoreRemindersUnits.DAY, + label: 'core.days', + }, + { + value: CoreRemindersUnits.WEEK, + label: 'core.weeks', + }, + ]; + + /** + * Set custom reminder. + */ + set(): void { + // Return it as an object because 0 means undefined if not. + PopoverController.dismiss({ value: this.customValue, unit: this.customUnits }); + } + + /** + * Close popup. + */ + cancel(): void { + PopoverController.dismiss(); + } + +} diff --git a/src/core/features/reminders/components/set-reminder-menu/set-reminder-menu.html b/src/core/features/reminders/components/set-reminder-menu/set-reminder-menu.html new file mode 100644 index 000000000..85c09e03e --- /dev/null +++ b/src/core/features/reminders/components/set-reminder-menu/set-reminder-menu.html @@ -0,0 +1,35 @@ + + + +

{{ 'core.reminders.setareminder' | translate }}

+
+
+
+ + + + + +

{{ option.label }}

+
+ +
+ + + + +

{{ 'core.reminders.custom' | translate }}

+

{{ customLabel }}

+
+ +
+ + + +

{{ noReminderLabel | translate }}

+
+ +
+ +
diff --git a/src/core/features/reminders/components/set-reminder-menu/set-reminder-menu.scss b/src/core/features/reminders/components/set-reminder-menu/set-reminder-menu.scss new file mode 100644 index 000000000..db4708ab3 --- /dev/null +++ b/src/core/features/reminders/components/set-reminder-menu/set-reminder-menu.scss @@ -0,0 +1,3 @@ +ion-item.border-top { + border-top: 1px solid var(--stroke); +} 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 new file mode 100644 index 000000000..951886057 --- /dev/null +++ b/src/core/features/reminders/components/set-reminder-menu/set-reminder-menu.ts @@ -0,0 +1,152 @@ +// (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 { AddonCalendarProvider } from '@addons/calendar/services/calendar'; +import { Component, Input, OnInit } from '@angular/core'; +import { CoreReminders, CoreRemindersUnits, CoreReminderValueAndUnit } from '@features/reminders/services/reminders'; +import { CoreDomUtils } from '@services/utils/dom'; +import { CoreUtils } from '@services/utils/utils'; +import { PopoverController } from '@singletons'; +import { CoreRemindersSetReminderCustomComponent } from '../set-reminder-custom/set-reminder-custom'; + +/** + * This component is meant to display a popover with the reminder options. + */ +@Component({ + templateUrl: 'set-reminder-menu.html', + styleUrls: ['set-reminder-menu.scss'], +}) +export class CoreRemindersSetReminderMenuComponent implements OnInit { + + @Input() initialValue?: CoreReminderValueAndUnit; + @Input() noReminderLabel = ''; + + currentValue = '0m'; + customLabel = ''; + + protected customValue = 10; + protected customUnits = CoreRemindersUnits.MINUTE; + + presetOptions = [ + { + radioValue: '0m', + value: 0, + unit: CoreRemindersUnits.MINUTE, + label: '', + }, + { + radioValue: '1h', + value: 1, + unit: CoreRemindersUnits.HOUR, + label: '', + }, + { + radioValue: '12h', + value: 12, + unit: CoreRemindersUnits.HOUR, + label: '', + }, + { + radioValue: '1d', + value: 1, + unit: CoreRemindersUnits.DAY, + label: '', + }, + ]; + + /** + * @inheritdoc + */ + async ngOnInit(): Promise { + this.presetOptions.forEach((option) => { + option.label = CoreReminders.getUnitValueLabel(option.value, option.unit); + }); + + if (!this.initialValue) { + return; + } + + if (this.initialValue.value === AddonCalendarProvider.DEFAULT_NOTIFICATION_DISABLED) { + this.currentValue = 'disabled'; + } else { + // Search if it's one of the preset options. + const option = this.presetOptions.find(option => + option.value === this.initialValue?.value && option.unit === this.initialValue.unit); + + if (option) { + this.currentValue = option.radioValue; + } else { + // It's a custom value. + this.currentValue = 'custom'; + this.customValue = this.initialValue.value; + this.customUnits = this.initialValue.unit; + this.customLabel = CoreReminders.getUnitValueLabel(this.customValue, this.customUnits); + } + } + } + + /** + * Set the reminder. + * + * @param value Value to set. + */ + setReminder(value: string): void { + // Return it as an object because 0 means undefined if not. + if (value === 'disabled') { + PopoverController.dismiss({ timeBefore: AddonCalendarProvider.DEFAULT_NOTIFICATION_DISABLED }); + + return; + } + + const option = this.presetOptions.find(option => option.radioValue === value); + if (!option) { + return; + } + + PopoverController.dismiss({ timeBefore: option.unit * option.value }); + } + + /** + * Custom value input clicked. + * + * @param ev Click event. + */ + async setCustom(ev: Event): Promise { + const reminderTime = await CoreDomUtils.openPopover({ + component: CoreRemindersSetReminderCustomComponent, + componentProps: { + customValue: this.customValue, + customUnits: this.customUnits, + }, + waitForDismissCompleted: true, // To be able to close parent popup. + event: ev, + }); + + if (reminderTime === undefined) { + // User canceled. + return; + } + + this.currentValue = 'custom'; + this.customValue = reminderTime.value; + this.customUnits = reminderTime.unit; + this.customLabel = CoreReminders.getUnitValueLabel(this.customValue, this.customUnits); + + // Let the dimissed popover to be removed. + await CoreUtils.nextTick(); + + PopoverController.dismiss({ timeBefore: Math.abs(this.customValue) * this.customUnits }); + } + +} diff --git a/src/core/features/reminders/lang.json b/src/core/features/reminders/lang.json new file mode 100644 index 000000000..d305761ef --- /dev/null +++ b/src/core/features/reminders/lang.json @@ -0,0 +1,11 @@ +{ + "atthetime": "At the time of the event", + "custom": "Custom...", + "customreminder": "Custom reminder", + "setareminder": "Set a reminder", + "daybefore": "{{time}} day before", + "daysbefore": "{{time}} days before", + "delete": "Delete reminder", + "timebefore": "{{value}} {{units}} before", + "units": "units" +} diff --git a/src/core/features/reminders/reminders.module.ts b/src/core/features/reminders/reminders.module.ts index 9c010befc..46ddaeee9 100644 --- a/src/core/features/reminders/reminders.module.ts +++ b/src/core/features/reminders/reminders.module.ts @@ -14,6 +14,7 @@ import { APP_INITIALIZER, NgModule, Type } from '@angular/core'; import { CORE_SITE_SCHEMAS } from '@services/sites'; +import { CoreRemindersComponentsModule } from './components/components.module'; import { REMINDERS_SITE_SCHEMA } from './services/database/reminders'; import { CoreReminders, CoreRemindersService } from './services/reminders'; @@ -23,6 +24,7 @@ export const CORE_REMINDERS_SERVICES: Type[] = [ @NgModule({ imports: [ + CoreRemindersComponentsModule, ], providers: [ { diff --git a/src/core/features/reminders/services/reminders.ts b/src/core/features/reminders/services/reminders.ts index a71cf1063..297178a8a 100644 --- a/src/core/features/reminders/services/reminders.ts +++ b/src/core/features/reminders/services/reminders.ts @@ -17,10 +17,36 @@ import { Injectable } from '@angular/core'; import { CoreLocalNotifications } from '@services/local-notifications'; import { CoreSites } from '@services/sites'; import { CoreTimeUtils } from '@services/utils/time'; -import { makeSingleton } from '@singletons'; +import { makeSingleton, Translate } from '@singletons'; import { CoreReminderDBRecord, REMINDERS_TABLE } from './database/reminders'; import { ILocalNotification } from '@ionic-native/local-notifications'; import { CorePlatform } from '@services/platform'; +import { CoreConstants } from '@/core/constants'; + +/** + * Units to set a reminder. + */ +export enum CoreRemindersUnits { + MINUTE = CoreConstants.SECONDS_MINUTE, + HOUR = CoreConstants.SECONDS_HOUR, + DAY = CoreConstants.SECONDS_DAY, + WEEK = CoreConstants.SECONDS_WEEK, +} + +const REMINDER_UNITS_LABELS = { + single: { + [CoreRemindersUnits.MINUTE]: 'core.minute', + [CoreRemindersUnits.HOUR]: 'core.hour', + [CoreRemindersUnits.DAY]: 'core.day', + [CoreRemindersUnits.WEEK]: 'core.week', + }, + multi: { + [CoreRemindersUnits.MINUTE]: 'core.minutes', + [CoreRemindersUnits.HOUR]: 'core.hours', + [CoreRemindersUnits.DAY]: 'core.days', + [CoreRemindersUnits.WEEK]: 'core.weeks', + }, +}; /** * Service to handle reminders. @@ -274,6 +300,80 @@ export class CoreRemindersService { })); } + /** + * Given a value and a unit, return the translated label. + * + * @param value Value. + * @param unit Unit. + * @param addDefaultLabel Whether to add the "Default" text. + * @return Translated label. + */ + getUnitValueLabel(value: number, unit: CoreRemindersUnits, addDefaultLabel = false): string { + if (value === AddonCalendarProvider.DEFAULT_NOTIFICATION_DISABLED) { + // TODO: It will need a migration of date to set 0 to -1 when needed. + return Translate.instant('core.settings.disabled'); + } + + if (value === 0) { + return Translate.instant('core.reminders.atthetime'); + } + + const unitsLabel = value === 1 ? + REMINDER_UNITS_LABELS.single[unit] : + REMINDER_UNITS_LABELS.multi[unit]; + + const label = Translate.instant('core.reminders.timebefore', { + units: Translate.instant(unitsLabel), + value: value, + }); + + if (addDefaultLabel) { + return Translate.instant('core.defaultvalue', { $a: label }); + } + + return label; + } + + /** + * Given a number of seconds, convert it to a unit&value format compatible with reminders. + * + * @param seconds Number of seconds. + * @return Value and unit. + */ + static convertSecondsToValueAndUnit(seconds?: number): CoreReminderValueAndUnit { + if (seconds === undefined || seconds < 0) { + return { + value: AddonCalendarProvider.DEFAULT_NOTIFICATION_DISABLED, + unit: CoreRemindersUnits.MINUTE, + }; + } else if (seconds === 0) { + return { + value: 0, + unit: CoreRemindersUnits.MINUTE, + }; + } else if (seconds % CoreRemindersUnits.WEEK === 0) { + return { + value: seconds / CoreRemindersUnits.WEEK, + unit: CoreRemindersUnits.WEEK, + }; + } else if (seconds % CoreRemindersUnits.DAY === 0) { + return { + value: seconds / CoreRemindersUnits.DAY, + unit: CoreRemindersUnits.DAY, + }; + } else if (seconds % CoreRemindersUnits.HOUR === 0) { + return { + value: seconds / CoreRemindersUnits.HOUR, + unit: CoreRemindersUnits.HOUR, + }; + } else { + return { + value: seconds / CoreRemindersUnits.MINUTE, + unit: CoreRemindersUnits.MINUTE, + }; + } + } + } export const CoreReminders = makeSingleton(CoreRemindersService); @@ -293,6 +393,14 @@ export type CoreReminderNotificationOptions = { title: string; }; +/** + * Value and unit for reminders. + */ +export type CoreReminderValueAndUnit = { + value: number; + unit: CoreRemindersUnits; +}; + export type CoreReminderSelector = { instanceId: number; component: string; diff --git a/src/core/services/utils/dom.ts b/src/core/services/utils/dom.ts index faddf4024..581880eeb 100644 --- a/src/core/services/utils/dom.ts +++ b/src/core/services/utils/dom.ts @@ -1138,7 +1138,7 @@ export class CoreDomUtilsProvider { /** * Show an alert modal with a button to close it. * - * @param title Title to show. + * @param header Title to show. * @param message Message to show. * @param buttonText Text of the button. * @param autocloseTime Number of milliseconds to wait to close the modal. If not defined, modal won't be closed. @@ -1230,7 +1230,7 @@ export class CoreDomUtilsProvider { /** * Show an alert modal with a button to close it, translating the values supplied. * - * @param title Title to show. + * @param header Title to show. * @param message Message to show. * @param buttonText Text of the button. * @param autocloseTime Number of milliseconds to wait to close the modal. If not defined, modal won't be closed. @@ -1669,7 +1669,6 @@ export class CoreDomUtilsProvider { * @param needsTranslate Whether the 'text' needs to be translated. * @param duration Duration in ms of the dimissable toast. * @param cssClass Class to add to the toast. - * @param dismissOnPageChange Dismiss the Toast on page change. * @return Toast instance. */ async showToast(