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 index 3002fc5fe..052241aa9 100644 --- a/src/addons/calendar/components/reminder-time-modal/reminder-time-modal.html +++ b/src/addons/calendar/components/reminder-time-modal/reminder-time-modal.html @@ -11,49 +11,52 @@ - - - - - {{ 'core.settings.disabled' | translate }} - - - - - - {{ option.label }} - - - + + + + + + {{ 'core.settings.disabled' | translate }} + + + + + + {{ option.label }} + + + - - - - {{ 'core.custom' | translate }} - - - - - + + + + {{ 'core.custom' | translate }} + + + + + - - - - + + + + - - {{ 'addon.calendar.units' | translate }} - - - {{ option.label | translate }} - - - - - + + {{ 'addon.calendar.units' | translate }} + + + {{ option.label | translate }} + + + + + - - {{ 'core.done' | 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 index f505fde21..871530664 100644 --- a/src/addons/calendar/components/reminder-time-modal/reminder-time-modal.ts +++ b/src/addons/calendar/components/reminder-time-modal/reminder-time-modal.ts @@ -15,6 +15,7 @@ import { AddonCalendar, AddonCalendarReminderUnits, AddonCalendarValueAndUnit } from '@addons/calendar/services/calendar'; import { Component, Input, OnInit } from '@angular/core'; import { CoreDomUtils } from '@services/utils/dom'; +import { CoreUtils } from '@services/utils/utils'; import { ModalController } from '@singletons'; /** @@ -153,4 +154,24 @@ export class AddonCalendarReminderTimeModalComponent implements OnInit { } } + /** + * Custom value input clicked. + * + * @param ev Click event. + */ + async customInputClicked(ev: Event): Promise { + if (this.radioValue === 'custom') { + return; + } + + this.radioValue = 'custom'; + + await CoreUtils.nextTick(); + + const target = ev.target; + if (target && 'focus' in target) { + target.focus(); + } + } + } diff --git a/src/addons/calendar/pages/day/day.page.ts b/src/addons/calendar/pages/day/day.page.ts index be2c15588..5c7e7c4b9 100644 --- a/src/addons/calendar/pages/day/day.page.ts +++ b/src/addons/calendar/pages/day/day.page.ts @@ -374,7 +374,9 @@ export class AddonCalendarDayPage implements OnInit, OnDestroy { const selectedDay = this.manager?.getSelectedItem(); if (selectedDay) { - params.timestamp = selectedDay.moment.unix() * 1000; + // Use current time but in the specified day. + const now = moment(); + params.timestamp = selectedDay.moment.clone().set({ hour: now.hour(), minute: now.minute() }).unix() * 1000; } } 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 d7bcfd094..c1807d35f 100644 --- a/src/addons/calendar/pages/edit-event/edit-event.page.ts +++ b/src/addons/calendar/pages/edit-event/edit-event.page.ts @@ -520,7 +520,7 @@ export class AddonCalendarEditEventPage implements OnInit, OnDestroy, CanLeave { try { const result = await AddonCalendar.submitEvent(this.eventId, data, { - reminders: this.reminders, + reminders: this.eventId ? [] : this.reminders, // Only allow adding reminders for new events. }); event = result.event; @@ -638,7 +638,8 @@ export class AddonCalendarEditEventPage implements OnInit, OnDestroy, CanLeave { * @return Promise resolved when done. */ protected async initReminders(): Promise { - if (!this.notificationsEnabled) { + // Don't init reminders when editing an event. Right now, only allow adding reminders for new events. + if (!this.notificationsEnabled || this.eventId) { return; } diff --git a/src/addons/calendar/pages/event/event.html b/src/addons/calendar/pages/event/event.html index 0b21ac1f4..ab3c5bcb8 100644 --- a/src/addons/calendar/pages/event/event.html +++ b/src/addons/calendar/pages/event/event.html @@ -136,7 +136,8 @@ 0" class="ion-text-wrap" [class.item-dimmed]="reminder.timestamp <= currentTime"> - {{ reminder.label }} + {{ reminder.label }} + {{ reminder.sublabel }} diff --git a/src/addons/calendar/services/calendar-helper.ts b/src/addons/calendar/services/calendar-helper.ts index a4f3a9479..dce3c6fc5 100644 --- a/src/addons/calendar/services/calendar-helper.ts +++ b/src/addons/calendar/services/calendar-helper.ts @@ -37,6 +37,7 @@ import { AddonCalendarSyncInvalidateEvent } from './calendar-sync'; import { AddonCalendarOfflineEventDBRecord } from './database/calendar-offline'; import { CoreCategoryData } from '@features/courses/services/courses'; import { AddonCalendarReminderDBRecord } from './database/calendar'; +import { CoreTimeUtils } from '@services/utils/time'; /** * Context levels enumeration. @@ -329,6 +330,9 @@ export class AddonCalendarHelperProvider { if (reminder.value && reminder.unit) { reminder.label = AddonCalendar.getUnitValueLabel(reminder.value, reminder.unit, reminder.time === null); + if (reminder.timestamp) { + reminder.sublabel = CoreTimeUtils.userDate(reminder.timestamp * 1000, 'core.strftimedatetime'); + } } return reminder; @@ -796,4 +800,5 @@ export type AddonCalendarEventReminder = AddonCalendarReminderDBRecord & { unit?: AddonCalendarReminderUnits; // Units. timestamp?: number; // Timestamp (in seconds). label?: string; // Label to represent the reminder. + sublabel?: string; // Sub label. }; diff --git a/src/addons/calendar/services/calendar.ts b/src/addons/calendar/services/calendar.ts index ec8c8db11..d010a96d9 100644 --- a/src/addons/calendar/services/calendar.ts +++ b/src/addons/calendar/services/calendar.ts @@ -777,6 +777,7 @@ export class AddonCalendarProvider { const reminder: Partial = { eventid: event.id, time: time ?? null, + timecreated: Date.now(), }; const reminderId = await site.getDb().insertRecord(REMINDERS_TABLE, reminder); @@ -913,7 +914,7 @@ export class AddonCalendarProvider { async getEventReminders(id: number, siteId?: string): Promise { const site = await CoreSites.getSite(siteId); - return await site.getDb().getRecords(REMINDERS_TABLE, { eventid: id }, 'time ASC'); + return await site.getDb().getRecords(REMINDERS_TABLE, { eventid: id }, 'timecreated ASC, time ASC'); } /** @@ -1696,7 +1697,7 @@ export class AddonCalendarProvider { const event = await AddonCalendarOffline.saveEvent(eventId, formData, siteId); // Now save the reminders if any. - if (options.reminders) { + if (options.reminders?.length) { await CoreUtils.ignoreErrors( Promise.all(options.reminders.map((reminder) => this.addEventReminder(event, reminder.time, siteId))), ); @@ -1718,7 +1719,7 @@ export class AddonCalendarProvider { const event = await this.submitEventOnline(eventId, formData, siteId); // Now save the reminders if any. - if (options.reminders) { + if (options.reminders?.length) { await CoreUtils.ignoreErrors( Promise.all(options.reminders.map((reminder) => this.addEventReminder(event, reminder.time, siteId))), ); diff --git a/src/addons/calendar/services/database/calendar.ts b/src/addons/calendar/services/database/calendar.ts index b21928140..1349eb9be 100644 --- a/src/addons/calendar/services/database/calendar.ts +++ b/src/addons/calendar/services/database/calendar.ts @@ -22,7 +22,7 @@ import { AddonCalendar, AddonCalendarEventType, AddonCalendarProvider } from '.. * Database variables for AddonCalendarProvider service. */ export const EVENTS_TABLE = 'addon_calendar_events_3'; -export const REMINDERS_TABLE = 'addon_calendar_reminders'; +export const REMINDERS_TABLE = 'addon_calendar_reminders_2'; export const CALENDAR_SITE_SCHEMA: CoreSiteSchema = { name: 'AddonCalendarProvider', version: 4, @@ -195,6 +195,10 @@ export const CALENDAR_SITE_SCHEMA: CoreSiteSchema = { name: 'time', type: 'INTEGER', }, + { + name: 'timecreated', + type: 'INTEGER', + }, ], uniqueKeys: [ ['eventid', 'time'], @@ -228,7 +232,16 @@ export const CALENDAR_SITE_SCHEMA: CoreSiteSchema = { } // Migrate reminders. New format @since 4.0. - const records = await db.getAllRecords(REMINDERS_TABLE); + const oldTable = 'addon_calendar_reminders'; + + try { + await db.tableExists(oldTable); + } catch (error) { + // Old table does not exist, ignore. + return; + } + + const records = await db.getAllRecords(oldTable); const events: Record = {}; await Promise.all(records.map(async (record) => { @@ -237,9 +250,7 @@ export const CALENDAR_SITE_SCHEMA: CoreSiteSchema = { try { events[record.eventid] = await db.getRecord(EVENTS_TABLE, { id: record.eventid }); } catch { - // Event not found in local DB, shouldn't happen. Delete the reminder. - await db.deleteRecords(REMINDERS_TABLE, { id: record.id }); - + // Event not found in local DB, shouldn't happen. Ignore the reminder. return; } } @@ -248,9 +259,7 @@ export const CALENDAR_SITE_SCHEMA: CoreSiteSchema = { // Default reminder. Use null now. record.time = null; } else if (record.time > events[record.eventid].timestart) { - // Reminder is after the event, delete it. - await db.deleteRecords(REMINDERS_TABLE, { id: record.id }); - + // Reminder is after the event, ignore it. return; } else { // Remove seconds from the old reminder, it could include seconds by mistake. @@ -259,6 +268,12 @@ export const CALENDAR_SITE_SCHEMA: CoreSiteSchema = { return db.insertRecord(REMINDERS_TABLE, record); })); + + try { + await db.dropTable(oldTable); + } catch (error) { + // Error deleting old table, ignore. + } } }, }; @@ -308,4 +323,5 @@ export type AddonCalendarReminderDBRecord = { id: number; eventid: number; time: number | null; // Number of seconds before the event, null for default time. + timecreated?: number | null; };
{{ 'core.settings.disabled' | translate }}
{{ option.label }}
{{ 'core.custom' | translate }}
{{ reminder.label }}
{{ reminder.sublabel }}