From 1466c543cab88aa340a820e3ce72af427bb82a3b Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Tue, 11 Jan 2022 08:25:06 +0100 Subject: [PATCH 1/2] MOBILE-3951 calendar: Schedule notifications from service --- .../calendar/components/calendar/calendar.ts | 56 +++++-------------- .../upcoming-events/upcoming-events.ts | 11 ---- src/addons/calendar/pages/day/day.page.ts | 15 ----- src/addons/calendar/pages/event/event.page.ts | 7 +-- src/addons/calendar/services/calendar.ts | 33 ++++++++++- 5 files changed, 46 insertions(+), 76 deletions(-) diff --git a/src/addons/calendar/components/calendar/calendar.ts b/src/addons/calendar/components/calendar/calendar.ts index ed3e500c7..64cd0807d 100644 --- a/src/addons/calendar/components/calendar/calendar.ts +++ b/src/addons/calendar/components/calendar/calendar.ts @@ -41,7 +41,6 @@ import { AddonCalendarFilter, AddonCalendarHelper } from '../../services/calenda import { AddonCalendarOffline } from '../../services/calendar-offline'; import { CoreCategoryData, CoreCourses } from '@features/courses/services/courses'; import { CoreApp } from '@services/app'; -import { CoreLocalNotifications } from '@services/local-notifications'; import { CoreSwipeSlidesComponent } from '@components/swipe-slides/swipe-slides'; import { CoreSwipeSlidesDynamicItem, @@ -78,7 +77,6 @@ export class AddonCalendarCalendarComponent implements OnInit, DoCheck, OnDestro protected differ: KeyValueDiffer; // To detect changes in the data input. // Observers and listeners. protected undeleteEventObserver: CoreEventObserver; - protected obsDefaultTimeChange?: CoreEventObserver; protected managerUnsubscribe?: () => void; constructor( @@ -86,23 +84,6 @@ export class AddonCalendarCalendarComponent implements OnInit, DoCheck, OnDestro ) { this.currentSiteId = CoreSites.getCurrentSiteId(); - if (CoreLocalNotifications.isAvailable()) { - // Re-schedule events if default time changes. - this.obsDefaultTimeChange = CoreEvents.on(AddonCalendarProvider.DEFAULT_NOTIFICATION_TIME_CHANGED, () => { - this.manager?.getSource().getItems()?.forEach((month) => { - if (!month.loaded) { - return; - } - - month.weeks?.forEach((week) => { - week.days.forEach((day) => { - AddonCalendar.scheduleEventsNotifications(day.eventsFormated || []); - }); - }); - }); - }, this.currentSiteId); - } - // Listen for events "undeleted" (offline). this.undeleteEventObserver = CoreEvents.on( AddonCalendarProvider.UNDELETED_EVENT_EVENT, @@ -329,7 +310,6 @@ export class AddonCalendarCalendarComponent implements OnInit, DoCheck, OnDestro */ ngOnDestroy(): void { this.undeleteEventObserver?.off(); - this.obsDefaultTimeChange?.off(); this.managerUnsubscribe && this.managerUnsubscribe(); } @@ -577,30 +557,22 @@ class AddonCalendarMonthSlidesItemsManagerSource extends CoreSwipeSlidesDynamicI weeks.forEach((week) => { week.days.forEach((day) => { + if (this.deletedEvents.length) { + // Mark as deleted the events that were deleted in offline. + day.eventsFormated?.forEach((event) => { + event.deleted = this.deletedEvents.indexOf(event.id) != -1; + }); + } - // Schedule notifications for the events retrieved (only future events will be scheduled). - AddonCalendar.scheduleEventsNotifications(day.eventsFormated || []); + if (this.offlineEditedEventsIds.length) { + // Remove the online events that were modified in offline. + day.events = day.events.filter((event) => this.offlineEditedEventsIds.indexOf(event.id) == -1); + } - if (monthOfflineEvents || this.deletedEvents.length) { - // There is offline data, merge it. - - if (this.deletedEvents.length) { - // Mark as deleted the events that were deleted in offline. - day.eventsFormated?.forEach((event) => { - event.deleted = this.deletedEvents.indexOf(event.id) != -1; - }); - } - - if (this.offlineEditedEventsIds.length) { - // Remove the online events that were modified in offline. - day.events = day.events.filter((event) => this.offlineEditedEventsIds.indexOf(event.id) == -1); - } - - if (monthOfflineEvents && monthOfflineEvents[day.mday] && day.eventsFormated) { - // Add the offline events (either new or edited). - day.eventsFormated = - AddonCalendarHelper.sortEvents(day.eventsFormated.concat(monthOfflineEvents[day.mday])); - } + if (monthOfflineEvents && monthOfflineEvents[day.mday] && day.eventsFormated) { + // Add the offline events (either new or edited). + day.eventsFormated = + AddonCalendarHelper.sortEvents(day.eventsFormated.concat(monthOfflineEvents[day.mday])); } }); }); diff --git a/src/addons/calendar/components/upcoming-events/upcoming-events.ts b/src/addons/calendar/components/upcoming-events/upcoming-events.ts index a11c5f81b..8740e28fa 100644 --- a/src/addons/calendar/components/upcoming-events/upcoming-events.ts +++ b/src/addons/calendar/components/upcoming-events/upcoming-events.ts @@ -25,7 +25,6 @@ import { AddonCalendarHelper, AddonCalendarFilter } from '../../services/calenda import { AddonCalendarOffline } from '../../services/calendar-offline'; import { CoreCategoryData, CoreCourses } from '@features/courses/services/courses'; import { CoreConstants } from '@/core/constants'; -import { CoreLocalNotifications } from '@services/local-notifications'; /** * Component that displays upcoming events. @@ -58,19 +57,12 @@ export class AddonCalendarUpcomingEventsComponent implements OnInit, DoCheck, On // Observers. protected undeleteEventObserver: CoreEventObserver; - protected obsDefaultTimeChange?: CoreEventObserver; constructor( differs: KeyValueDiffers, ) { this.currentSiteId = CoreSites.getCurrentSiteId(); - if (CoreLocalNotifications.isAvailable()) { // Re-schedule events if default time changes. - this.obsDefaultTimeChange = CoreEvents.on(AddonCalendarProvider.DEFAULT_NOTIFICATION_TIME_CHANGED, () => { - AddonCalendar.scheduleEventsNotifications(this.onlineEvents); - }, this.currentSiteId); - } - // Listen for events "undeleted" (offline). this.undeleteEventObserver = CoreEvents.on( AddonCalendarProvider.UNDELETED_EVENT_EVENT, @@ -174,8 +166,6 @@ export class AddonCalendarUpcomingEventsComponent implements OnInit, DoCheck, On // Don't pass courseId and categoryId, we'll filter them locally. const result = await AddonCalendar.getUpcomingEvents(); this.onlineEvents = await Promise.all(result.events.map((event) => AddonCalendarHelper.formatEventData(event))); - // Schedule notifications for the events retrieved. - AddonCalendar.scheduleEventsNotifications(this.onlineEvents); // Merge the online events with offline data. this.events = this.mergeEvents(); // Filter events by course. @@ -313,7 +303,6 @@ export class AddonCalendarUpcomingEventsComponent implements OnInit, DoCheck, On */ ngOnDestroy(): void { this.undeleteEventObserver?.off(); - this.obsDefaultTimeChange?.off(); } } diff --git a/src/addons/calendar/pages/day/day.page.ts b/src/addons/calendar/pages/day/day.page.ts index b806ed84c..03b10b0b2 100644 --- a/src/addons/calendar/pages/day/day.page.ts +++ b/src/addons/calendar/pages/day/day.page.ts @@ -16,7 +16,6 @@ import { Component, OnInit, OnDestroy, ViewChild } from '@angular/core'; import { IonRefresher } from '@ionic/angular'; import { CoreApp } from '@services/app'; import { CoreEventObserver, CoreEvents } from '@singletons/events'; -import { CoreLocalNotifications } from '@services/local-notifications'; import { CoreSites } from '@services/sites'; import { CoreDomUtils } from '@services/utils/dom'; import { CoreTimeUtils } from '@services/utils/time'; @@ -70,7 +69,6 @@ export class AddonCalendarDayPage implements OnInit, OnDestroy { protected syncObserver: CoreEventObserver; protected manualSyncObserver: CoreEventObserver; protected onlineObserver: Subscription; - protected obsDefaultTimeChange?: CoreEventObserver; protected filterChangedObserver: CoreEventObserver; protected managerUnsubscribe?: () => void; @@ -93,15 +91,6 @@ export class AddonCalendarDayPage implements OnInit, OnDestroy { constructor() { this.currentSiteId = CoreSites.getCurrentSiteId(); - if (CoreLocalNotifications.isAvailable()) { - // Re-schedule events if default time changes. - this.obsDefaultTimeChange = CoreEvents.on(AddonCalendarProvider.DEFAULT_NOTIFICATION_TIME_CHANGED, () => { - this.manager?.getSource().getItems()?.forEach(day => { - AddonCalendar.scheduleEventsNotifications(day.onlineEvents || []); - }); - }, this.currentSiteId); - } - // Listen for events added. When an event is added, reload the data. this.newEventObserver = CoreEvents.on( AddonCalendarProvider.NEW_EVENT_EVENT, @@ -464,7 +453,6 @@ export class AddonCalendarDayPage implements OnInit, OnDestroy { this.manualSyncObserver?.off(); this.onlineObserver?.unsubscribe(); this.filterChangedObserver?.off(); - this.obsDefaultTimeChange?.off(); this.managerUnsubscribe && this.managerUnsubscribe(); } @@ -684,9 +672,6 @@ class AddonCalendarDaySlidesItemsManagerSource extends CoreSwipeSlidesDynamicIte } } - // Schedule notifications for the events retrieved (only future events will be scheduled). - AddonCalendar.scheduleEventsNotifications(preloadedDay.onlineEvents || []); - // Merge the online events with offline data. preloadedDay.events = this.mergeEvents(preloadedDay); diff --git a/src/addons/calendar/pages/event/event.page.ts b/src/addons/calendar/pages/event/event.page.ts index ac44adc68..e335e6b78 100644 --- a/src/addons/calendar/pages/event/event.page.ts +++ b/src/addons/calendar/pages/event/event.page.ts @@ -129,10 +129,6 @@ export class AddonCalendarEventPage implements OnInit, OnDestroy { // Reload reminders if default notification time changes. this.defaultTimeChangedObserver = CoreEvents.on(AddonCalendarProvider.DEFAULT_NOTIFICATION_TIME_CHANGED, () => { this.loadReminders(); - - if (this.event) { - AddonCalendar.scheduleEventsNotifications([this.event]); - } }, this.currentSiteId); // Set and update current time. Use a 5 seconds error margin. @@ -225,9 +221,8 @@ export class AddonCalendarEventPage implements OnInit, OnDestroy { return; // At this point we should always have the event, adding this check to avoid TS errors. } - // Load reminders, and re-schedule them if needed (maybe the event time has changed). + // Load reminders. this.loadReminders(); - AddonCalendar.scheduleEventsNotifications([this.event]); // Reset some of the calculated data. this.categoryPath = ''; diff --git a/src/addons/calendar/services/calendar.ts b/src/addons/calendar/services/calendar.ts index 69473fb05..6ec1cbc0e 100644 --- a/src/addons/calendar/services/calendar.ts +++ b/src/addons/calendar/services/calendar.ts @@ -39,6 +39,7 @@ import { SafeUrl } from '@angular/platform-browser'; import { CoreNavigator } from '@services/navigator'; import { AddonCalendarFilter } from './calendar-helper'; import { AddonCalendarSyncEvents, AddonCalendarSyncProvider } from './calendar-sync'; +import { CoreEvents } from '@singletons/events'; const ROOT_CACHE_KEY = 'mmaCalendar:'; @@ -351,6 +352,28 @@ export class AddonCalendarProvider { }, ); + if (CoreLocalNotifications.isAvailable()) { + CoreEvents.on(AddonCalendarProvider.DEFAULT_NOTIFICATION_TIME_CHANGED, async (data) => { + const site = await CoreSites.getSite(data.siteId); + + // Get all the events that have a default reminder. + const query = 'SELECT events.*, reminders.id AS reminderid ' + + 'FROM ' + EVENTS_TABLE + ' events ' + + 'INNER JOIN ' + REMINDERS_TABLE + ' reminders ON events.id = reminders.eventid ' + + 'WHERE reminders.time IS NULL'; + + const result = await site.getDb().execute(query); + + // Reschedule all the default reminders. + for (let i = 0; i < result.rows.length; i++) { + const event = result.rows.item(i) as AddonCalendarEventDBRecord & { + reminderid: number; + }; + + this.scheduleEventNotification(event, event.reminderid, null, site.getId()); + } + }); + } } /** @@ -674,6 +697,9 @@ export class AddonCalendarProvider { const response: AddonCalendarGetCalendarEventByIdWSResponse = await site.read('core_calendar_get_calendar_event_by_id', params, preSets); + this.storeEventInLocalDb(response.event, { siteId }); + this.scheduleEventsNotifications([response.event], siteId); + return response.event; } catch (error) { try { @@ -837,6 +863,7 @@ export class AddonCalendarProvider { } const response: AddonCalendarCalendarDay = await site.read('core_calendar_get_calendar_day_view', params, preSets); this.storeEventsInLocalDB(response.events, { siteId }); + this.scheduleEventsNotifications(response.events, siteId); return response; } @@ -1040,7 +1067,8 @@ export class AddonCalendarProvider { const response = await site.read('core_calendar_get_calendar_monthly_view', params, preSets); response.weeks.forEach((week) => { week.days.forEach((day) => { - this.storeEventsInLocalDB(day.events as AddonCalendarCalendarEvent[], { siteId }); + this.storeEventsInLocalDB(day.events, { siteId }); + this.scheduleEventsNotifications(day.events, siteId); }); }); @@ -1154,6 +1182,7 @@ export class AddonCalendarProvider { const response = await site.read('core_calendar_get_calendar_upcoming_view', params, preSets); this.storeEventsInLocalDB(response.events, { siteId }); + this.scheduleEventsNotifications(response.events, siteId); return response; } @@ -1512,7 +1541,7 @@ export class AddonCalendarProvider { const promises = events.map(async (event) => { if (event.timestart * 1000 <= Date.now()) { // The event has already started, don't schedule it. - return this.deleteLocalEvent(event.id, siteId); + return; } const reminders = await this.getEventReminders(event.id, siteId); From cca049eff2139538c3e0dc65dbd73bb99b0fdc46 Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Tue, 11 Jan 2022 10:35:14 +0100 Subject: [PATCH 2/2] MOBILE-3951 ci: Use https in github URLs --- .github/workflows/performance.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/performance.yml b/.github/workflows/performance.yml index 0f886e523..923c2d09f 100644 --- a/.github/workflows/performance.yml +++ b/.github/workflows/performance.yml @@ -18,9 +18,9 @@ jobs: node-version: '${{ steps.nvmrc.outputs.node_version }}' - name: Additional checkouts run: | - git clone --branch master --depth 1 git://github.com/moodle/moodle $GITHUB_WORKSPACE/moodle - git clone --branch integration --depth 1 git://github.com/moodlehq/moodle-local_moodlemobileapp $GITHUB_WORKSPACE/moodle/local/moodlemobileapp - git clone --branch master --depth 1 git://github.com/moodlehq/moodle-docker $GITHUB_WORKSPACE/moodle-docker + git clone --branch master --depth 1 https://github.com/moodle/moodle $GITHUB_WORKSPACE/moodle + git clone --branch integration --depth 1 https://github.com/moodlehq/moodle-local_moodlemobileapp $GITHUB_WORKSPACE/moodle/local/moodlemobileapp + git clone --branch master --depth 1 https://github.com/moodlehq/moodle-docker $GITHUB_WORKSPACE/moodle-docker - name: Install npm packages run: npm ci - name: Generate Behat tests plugin