diff --git a/src/addon/calendar/calendar.module.ts b/src/addon/calendar/calendar.module.ts index 66ab9f237..28765fad6 100644 --- a/src/addon/calendar/calendar.module.ts +++ b/src/addon/calendar/calendar.module.ts @@ -19,12 +19,14 @@ import { AddonCalendarHelperProvider } from './providers/helper'; import { AddonCalendarSyncProvider } from './providers/calendar-sync'; import { AddonCalendarMainMenuHandler } from './providers/mainmenu-handler'; import { AddonCalendarSyncCronHandler } from './providers/sync-cron-handler'; +import { AddonCalendarViewLinkHandler } from './providers/view-link-handler'; import { CoreMainMenuDelegate } from '@core/mainmenu/providers/delegate'; import { CoreCronDelegate } from '@providers/cron'; import { CoreInitDelegate } from '@providers/init'; import { CoreLocalNotificationsProvider } from '@providers/local-notifications'; import { CoreLoginHelperProvider } from '@core/login/providers/helper'; import { CoreUpdateManagerProvider } from '@providers/update-manager'; +import { CoreContentLinksDelegate } from '@core/contentlinks/providers/delegate'; // List of providers (without handlers). export const ADDON_CALENDAR_PROVIDERS: any[] = [ @@ -45,17 +47,20 @@ export const ADDON_CALENDAR_PROVIDERS: any[] = [ AddonCalendarHelperProvider, AddonCalendarSyncProvider, AddonCalendarMainMenuHandler, - AddonCalendarSyncCronHandler + AddonCalendarSyncCronHandler, + AddonCalendarViewLinkHandler ] }) export class AddonCalendarModule { constructor(mainMenuDelegate: CoreMainMenuDelegate, calendarHandler: AddonCalendarMainMenuHandler, initDelegate: CoreInitDelegate, calendarProvider: AddonCalendarProvider, loginHelper: CoreLoginHelperProvider, localNotificationsProvider: CoreLocalNotificationsProvider, updateManager: CoreUpdateManagerProvider, - cronDelegate: CoreCronDelegate, syncHandler: AddonCalendarSyncCronHandler) { + cronDelegate: CoreCronDelegate, syncHandler: AddonCalendarSyncCronHandler, + contentLinksDelegate: CoreContentLinksDelegate, viewLinkHandler: AddonCalendarViewLinkHandler) { mainMenuDelegate.registerHandler(calendarHandler); cronDelegate.register(syncHandler); + contentLinksDelegate.registerHandler(viewLinkHandler); initDelegate.ready().then(() => { calendarProvider.scheduleAllSitesEventsNotifications(); diff --git a/src/addon/calendar/components/calendar/addon-calendar-calendar.html b/src/addon/calendar/components/calendar/addon-calendar-calendar.html index 7c607ca63..ea373d297 100644 --- a/src/addon/calendar/components/calendar/addon-calendar-calendar.html +++ b/src/addon/calendar/components/calendar/addon-calendar-calendar.html @@ -40,7 +40,7 @@

- + {{ event.timestart * 1000 | coreFormatDate: timeFormat }} diff --git a/src/addon/calendar/components/calendar/calendar.ts b/src/addon/calendar/components/calendar/calendar.ts index 2b40b8b3f..2a94768f8 100644 --- a/src/addon/calendar/components/calendar/calendar.ts +++ b/src/addon/calendar/components/calendar/calendar.ts @@ -91,7 +91,7 @@ export class AddonCalendarCalendarComponent implements OnInit, OnChanges, OnDest const now = new Date(); this.year = this.initialYear ? Number(this.initialYear) : now.getFullYear(); - this.month = this.initialYear ? Number(this.initialYear) : now.getMonth() + 1; + this.month = this.initialMonth ? Number(this.initialMonth) : now.getMonth() + 1; this.canNavigate = typeof this.canNavigate == 'undefined' ? true : this.utils.isTrueOrOne(this.canNavigate); this.fetchData(); @@ -328,31 +328,33 @@ export class AddonCalendarCalendarComponent implements OnInit, OnChanges, OnDest protected mergeEvents(): void { const monthOfflineEvents = this.offlineEvents[this.calendarHelper.getMonthId(this.year, this.month)]; - if (!monthOfflineEvents && !this.deletedEvents.length) { - // No offline events, nothing to merge. - return; - } - this.weeks.forEach((week) => { week.days.forEach((day) => { - if (this.deletedEvents.length) { - // Mark as deleted the events that were deleted in offline. - day.events.forEach((event) => { - event.deleted = this.deletedEvents.indexOf(event.id) != -1; - }); - } + // Format online events. + day.events.forEach(this.calendarHelper.formatEventData.bind(this.calendarHelper)); - if (this.offlineEditedEventsIds.length) { - // Remove the online events that were modified in offline. - day.events = day.events.filter((event) => { - return this.offlineEditedEventsIds.indexOf(event.id) == -1; - }); - } + if (monthOfflineEvents || this.deletedEvents.length) { + // There is offline data, merge it. - if (monthOfflineEvents && monthOfflineEvents[day.mday]) { - // Add the offline events (either new or edited). - day.events = this.sortEvents(day.events.concat(monthOfflineEvents[day.mday])); + if (this.deletedEvents.length) { + // Mark as deleted the events that were deleted in offline. + day.events.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) => { + return this.offlineEditedEventsIds.indexOf(event.id) == -1; + }); + } + + if (monthOfflineEvents && monthOfflineEvents[day.mday]) { + // Add the offline events (either new or edited). + day.events = this.sortEvents(day.events.concat(monthOfflineEvents[day.mday])); + } } }); }); diff --git a/src/addon/calendar/components/upcoming-events/addon-calendar-upcoming-events.html b/src/addon/calendar/components/upcoming-events/addon-calendar-upcoming-events.html index b338f0eca..0a4b7bb1e 100644 --- a/src/addon/calendar/components/upcoming-events/addon-calendar-upcoming-events.html +++ b/src/addon/calendar/components/upcoming-events/addon-calendar-upcoming-events.html @@ -8,7 +8,7 @@

-

+

{{ 'core.notsent' | translate }} diff --git a/src/addon/calendar/components/upcoming-events/upcoming-events.ts b/src/addon/calendar/components/upcoming-events/upcoming-events.ts index f358b5785..d362b6d6e 100644 --- a/src/addon/calendar/components/upcoming-events/upcoming-events.ts +++ b/src/addon/calendar/components/upcoming-events/upcoming-events.ts @@ -146,6 +146,8 @@ export class AddonCalendarUpcomingEventsComponent implements OnInit, OnChanges, fetchEvents(): Promise { // Don't pass courseId and categoryId, we'll filter them locally. return this.calendarProvider.getUpcomingEvents().then((result) => { + const promises = []; + this.onlineEvents = result.events; this.onlineEvents.forEach(this.calendarHelper.formatEventData.bind(this.calendarHelper)); @@ -158,8 +160,12 @@ export class AddonCalendarUpcomingEventsComponent implements OnInit, OnChanges, // Re-calculate the formatted time so it uses the device date. this.events.forEach((event) => { - event.formattedtime = this.calendarProvider.formatEventTime(event, this.timeFormat); + promises.push(this.calendarProvider.formatEventTime(event, this.timeFormat).then((time) => { + event.formattedtime = time; + })); }); + + return Promise.all(promises); }); } diff --git a/src/addon/calendar/pages/day/day.html b/src/addon/calendar/pages/day/day.html index e9b48bd52..134def736 100644 --- a/src/addon/calendar/pages/day/day.html +++ b/src/addon/calendar/pages/day/day.html @@ -49,7 +49,7 @@

-

+

{{ 'core.notsent' | translate }} diff --git a/src/addon/calendar/pages/day/day.ts b/src/addon/calendar/pages/day/day.ts index 924bfa0e7..43be54b5b 100644 --- a/src/addon/calendar/pages/day/day.ts +++ b/src/addon/calendar/pages/day/day.ts @@ -188,7 +188,7 @@ export class AddonCalendarDayPage implements OnInit, OnDestroy { * View loaded. */ ngOnInit(): void { - this.currentMoment = moment().year(this.year).month(this.month - 1).day(this.day); + this.currentMoment = moment().year(this.year).month(this.month - 1).date(this.day); this.fetchData(true, false); } @@ -273,6 +273,7 @@ export class AddonCalendarDayPage implements OnInit, OnDestroy { fetchEvents(): Promise { // Don't pass courseId and categoryId, we'll filter them locally. return this.calendarProvider.getDayEvents(this.year, this.month, this.day).then((result) => { + const promises = []; // Calculate the period name. We don't use the one in result because it's in server's language. this.periodName = this.timeUtils.userDate(new Date(this.year, this.month - 1, this.day).getTime(), @@ -288,9 +289,14 @@ export class AddonCalendarDayPage implements OnInit, OnDestroy { this.filterEvents(); // Re-calculate the formatted time so it uses the device date. + const dayTime = this.currentMoment.unix() * 1000; this.events.forEach((event) => { - event.formattedtime = this.calendarProvider.formatEventTime(event, this.timeFormat); + promises.push(this.calendarProvider.formatEventTime(event, this.timeFormat, true, dayTime).then((time) => { + event.formattedtime = time; + })); }); + + return Promise.all(promises); }); } diff --git a/src/addon/calendar/pages/event/event.html b/src/addon/calendar/pages/event/event.html index 23e55aac7..6e64b6fe0 100644 --- a/src/addon/calendar/pages/event/event.html +++ b/src/addon/calendar/pages/event/event.html @@ -29,18 +29,11 @@

+

{{ 'core.deletedoffline' | translate }}
- -

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

-

{{ event.timestart * 1000 | coreFormatDate }}

-
- -

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

-

{{ (event.timestart + event.timeduration) * 1000 | coreFormatDate }}

-

{{ 'core.course' | translate}}

diff --git a/src/addon/calendar/pages/event/event.ts b/src/addon/calendar/pages/event/event.ts index bfb45499c..7af265152 100644 --- a/src/addon/calendar/pages/event/event.ts +++ b/src/addon/calendar/pages/event/event.ts @@ -311,6 +311,13 @@ export class AddonCalendarEventPage implements OnDestroy { event.deleted = deleted; })); + // Re-calculate the formatted time so it uses the device date. + promises.push(this.calendarProvider.getCalendarTimeFormat().then((timeFormat) => { + this.calendarProvider.formatEventTime(event, timeFormat).then((time) => { + event.formattedtime = time; + }); + })); + return Promise.all(promises); }).catch((error) => { this.domUtils.showErrorModalDefault(error, 'addon.calendar.errorloadevent', true); diff --git a/src/addon/calendar/pages/index/index.html b/src/addon/calendar/pages/index/index.html index 099892df8..ca8e832f3 100644 --- a/src/addon/calendar/pages/index/index.html +++ b/src/addon/calendar/pages/index/index.html @@ -28,7 +28,7 @@ {{ 'core.hasdatatosync' | translate:{$a: 'addon.calendar.calendar' | translate} }} - + diff --git a/src/addon/calendar/pages/index/index.ts b/src/addon/calendar/pages/index/index.ts index 59088156b..341cf36b3 100644 --- a/src/addon/calendar/pages/index/index.ts +++ b/src/addon/calendar/pages/index/index.ts @@ -53,6 +53,8 @@ export class AddonCalendarIndexPage implements OnInit, OnDestroy { protected manualSyncObserver: any; protected onlineObserver: any; + year: number; + month: number; courseId: number; categoryId: number; canCreate = false; @@ -82,8 +84,12 @@ export class AddonCalendarIndexPage implements OnInit, OnDestroy { this.courseId = navParams.get('courseId'); this.eventId = navParams.get('eventId') || false; + this.year = navParams.get('year'); + this.month = navParams.get('month'); this.notificationsEnabled = localNotificationsProvider.isAvailable(); this.currentSiteId = sitesProvider.getCurrentSiteId(); + this.loadUpcoming = !!navParams.get('upcoming'); + this.showCalendar = !this.loadUpcoming; // Listen for events added. When an event is added, reload the data. this.newEventObserver = eventsProvider.on(AddonCalendarProvider.NEW_EVENT_EVENT, (data) => { diff --git a/src/addon/calendar/pages/list/list.ts b/src/addon/calendar/pages/list/list.ts index 1c7572e12..0b864a78a 100644 --- a/src/addon/calendar/pages/list/list.ts +++ b/src/addon/calendar/pages/list/list.ts @@ -53,7 +53,6 @@ export class AddonCalendarListPage implements OnDestroy { protected siteHomeId: number; protected obsDefaultTimeChange: any; protected eventId: number; - protected preSelectedCourseId: number; protected newEventObserver: any; protected discardedObserver: any; protected editEventObserver: any; @@ -101,7 +100,7 @@ export class AddonCalendarListPage implements OnDestroy { } this.eventId = navParams.get('eventId') || false; - this.preSelectedCourseId = navParams.get('courseId') || null; + this.courseId = navParams.get('courseId'); // Listen for events added. When an event is added, reload the data. this.newEventObserver = eventsProvider.on(AddonCalendarProvider.NEW_EVENT_EVENT, (data) => { @@ -284,12 +283,6 @@ export class AddonCalendarListPage implements OnDestroy { this.courses = result.courses; this.categoryId = result.categoryId; - if (this.preSelectedCourseId) { - this.filter.course = courses.find((course) => { - return course.id == this.preSelectedCourseId; - }); - } - return this.fetchEvents(refresh); })); diff --git a/src/addon/calendar/providers/calendar.ts b/src/addon/calendar/providers/calendar.ts index 3bb868034..e7c0800f3 100644 --- a/src/addon/calendar/providers/calendar.ts +++ b/src/addon/calendar/providers/calendar.ts @@ -18,7 +18,9 @@ import { CoreSitesProvider, CoreSiteSchema } from '@providers/sites'; import { CoreSite } from '@classes/site'; import { CoreCoursesProvider } from '@core/courses/providers/courses'; import { CoreAppProvider } from '@providers/app'; +import { CoreTextUtilsProvider } from '@providers/utils/text'; import { CoreTimeUtilsProvider } from '@providers/utils/time'; +import { CoreUrlUtilsProvider } from '@providers/utils/url'; import { CoreUtilsProvider } from '@providers/utils/utils'; import { CoreGroupsProvider } from '@providers/groups'; import { CoreConstants } from '@core/constants'; @@ -259,7 +261,9 @@ export class AddonCalendarProvider { private sitesProvider: CoreSitesProvider, private groupsProvider: CoreGroupsProvider, private coursesProvider: CoreCoursesProvider, + private textUtils: CoreTextUtilsProvider, private timeUtils: CoreTimeUtilsProvider, + private urlUtils: CoreUrlUtilsProvider, private localNotificationsProvider: CoreLocalNotificationsProvider, private configProvider: CoreConfigProvider, private utils: CoreUtilsProvider, @@ -487,15 +491,19 @@ export class AddonCalendarProvider { } /** - * Format event time. Equivalent to calendar_format_event_time. + * Format event time. Similar to calendar_format_event_time. * * @param {any} event Event to format. * @param {string} format Calendar time format (from getCalendarTimeFormat). * @param {boolean} [useCommonWords=true] Whether to use common words like "Today", "Yesterday", etc. + * @param {number} [seenDay] Timestamp of day currently seen. If set, the function will not add links to this day. * @param {number} [showTime=0] Determine the show time GMT timestamp. - * @return {string} Formatted event time. + * @param {string} [siteId] Site ID. If not defined, current site. + * @return {Promise} Promise resolved with the formatted event time. */ - formatEventTime(event: any, format: string, useCommonWords: boolean = true, showTime: number = 0): string { + formatEventTime(event: any, format: string, useCommonWords: boolean = true, seenDay?: number, showTime: number = 0, + siteId?: string): Promise { + const start = event.timestart * 1000, end = (event.timestart + event.timeduration) * 1000; let time; @@ -511,46 +519,50 @@ export class AddonCalendarProvider { this.timeUtils.userDate(end, format); } - if (!showTime) { - return this.getDayRepresentation(start, useCommonWords) + ', ' + time; - } else { - return time; - } - } else { // Event lasts more than one day. - const midnightStart = moment(start).startOf('day').unix() * 1000, - midnightEnd = moment(end).startOf('day').unix() * 1000, - timeStart = this.timeUtils.userDate(start, format), - timeEnd = this.timeUtils.userDate(end, format); - let dayStart = this.getDayRepresentation(start, useCommonWords) + ', ', - dayEnd = this.getDayRepresentation(end, useCommonWords) + ', '; + const timeStart = this.timeUtils.userDate(start, format), + timeEnd = this.timeUtils.userDate(end, format), + promises = []; - if (showTime == midnightStart) { - dayStart = ''; + // Don't use common words when the event lasts more than one day. + let dayStart = this.getDayRepresentation(start, false) + ', ', + dayEnd = this.getDayRepresentation(end, false) + ', '; + + // Add links to the days if needed. + if (dayStart && (!seenDay || !moment(seenDay).isSame(start, 'day'))) { + promises.push(this.getViewUrl('day', event.timestart, undefined, siteId).then((url) => { + dayStart = this.urlUtils.buildLink(url, dayStart); + })); + } + if (dayEnd && (!seenDay || !moment(seenDay).isSame(end, 'day'))) { + promises.push(this.getViewUrl('day', end / 1000, undefined, siteId).then((url) => { + dayEnd = this.urlUtils.buildLink(url, dayEnd); + })); } - if (showTime == midnightEnd) { - dayEnd = ''; - } - - // Set printable representation. - if (moment().isSame(start, 'day')) { - // Event starts today, don't display the day. - return timeStart + ' » ' + dayEnd + timeEnd; - } else { - // The event starts in the future, print both days. + return Promise.all(promises).then(() => { return dayStart + timeStart + ' » ' + dayEnd + timeEnd; - } + }); } - } else { // There is no time duration. - const time = this.timeUtils.userDate(start, format); + } else { + // There is no time duration. + time = this.timeUtils.userDate(start, format); + } - if (!showTime) { - return this.getDayRepresentation(start, useCommonWords) + ', ' + time.trim(); + if (!showTime) { + // Display day + time. + if (seenDay && moment(seenDay).isSame(start, 'day')) { + // This day is currently being displayed, don't add an link. + return Promise.resolve(this.getDayRepresentation(start, useCommonWords) + ', ' + time); } else { - return time; + // Add link to view the day. + return this.getViewUrl('day', event.timestart, undefined, siteId).then((url) => { + return this.urlUtils.buildLink(url, this.getDayRepresentation(start, useCommonWords)) + ', ' + time; + }); } + } else { + return Promise.resolve(time); } } @@ -841,6 +853,21 @@ export class AddonCalendarProvider { }); } + /** + * Return the normalised event type. + * Activity events are normalised to be course events. + * + * @param {any} event The event to get its type. + * @return {string} Event type. + */ + getEventType(event: any): string { + if (event.modulename) { + return 'course'; + } + + return event.eventtype; + } + /** * Remove an event reminder and cancel the notification. * @@ -1155,6 +1182,31 @@ export class AddonCalendarProvider { return this.getUpcomingEventsPrefixCacheKey() + (courseId ? courseId : '') + ':' + (categoryId ? categoryId : ''); } + /** + * Get URL to view a calendar. + * + * @param {string} view The view to load: 'month', 'day', 'upcoming', etc. + * @param {number} [time] Time to load. If not defined, current time. + * @param {string} [courseId] Course to load. If not defined, all courses. + * @param {string} [siteId] Site ID. If not defined, current site. + * @return {Promise} Promise resolved with the URL.x + */ + getViewUrl(view: string, time?: number, courseId?: string, siteId?: string): Promise { + return this.sitesProvider.getSite(siteId).then((site) => { + let url = this.textUtils.concatenatePaths(site.getURL(), 'calendar/view.php?view=' + view); + + if (time) { + url += '&time=' + time; + } + + if (courseId) { + url += '&course=' + courseId; + } + + return url; + }); + } + /** * Get the week days, already ordered according to a specified starting day. * diff --git a/src/addon/calendar/providers/helper.ts b/src/addon/calendar/providers/helper.ts index 225ec7ffb..575500c16 100644 --- a/src/addon/calendar/providers/helper.ts +++ b/src/addon/calendar/providers/helper.ts @@ -54,7 +54,7 @@ export class AddonCalendarHelperProvider { const types = {}; events.forEach((event) => { - types[event.eventtype] = true; + types[event.formattedType || event.eventtype] = true; if (event.islastday) { day.haslastdayofevent = true; @@ -133,6 +133,8 @@ export class AddonCalendarHelperProvider { e.moduleIcon = e.icon; } + e.formattedType = this.calendarProvider.getEventType(e); + if (typeof e.duration != 'undefined') { // It's an offline event, add some calculated data. e.format = 1; diff --git a/src/addon/calendar/providers/view-link-handler.ts b/src/addon/calendar/providers/view-link-handler.ts new file mode 100644 index 000000000..e0ba641c0 --- /dev/null +++ b/src/addon/calendar/providers/view-link-handler.ts @@ -0,0 +1,113 @@ +// (C) Copyright 2015 Martin Dougiamas +// +// 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 { Injectable } from '@angular/core'; +import { CoreContentLinksHandlerBase } from '@core/contentlinks/classes/base-handler'; +import { CoreContentLinksAction } from '@core/contentlinks/providers/delegate'; +import { CoreContentLinksHelperProvider } from '@core/contentlinks/providers/helper'; +import { AddonCalendarProvider } from './calendar'; + +/** + * Content links handler for calendar view page. + */ +@Injectable() +export class AddonCalendarViewLinkHandler extends CoreContentLinksHandlerBase { + name = 'AddonCalendarViewLinkHandler'; + pattern = /\/calendar\/view\.php/; + + protected SUPPORTED_VIEWS = ['month', 'mini', 'minithree', 'day', 'upcoming', 'upcoming_mini']; + + constructor(private linkHelper: CoreContentLinksHelperProvider, private calendarProvider: AddonCalendarProvider) { + super(); + } + + /** + * Get the list of actions for a link (url). + * + * @param {string[]} siteIds List of sites the URL belongs to. + * @param {string} url The URL to treat. + * @param {any} params The params of the URL. E.g. 'mysite.com?id=1' -> {id: 1} + * @param {number} [courseId] Course ID related to the URL. Optional but recommended. + * @return {CoreContentLinksAction[]|Promise} List of (or promise resolved with list of) actions. + */ + getActions(siteIds: string[], url: string, params: any, courseId?: number): + CoreContentLinksAction[] | Promise { + return [{ + action: (siteId, navCtrl?): void => { + if (!params.view || params.view == 'month' || params.view == 'mini' || params.view == 'minithree') { + // Monthly view, open the calendar tab. + const stateParams: any = { + courseId: params.course + }, + timestamp = params.time ? params.time * 1000 : Date.now(); + + const date = new Date(timestamp); + stateParams.year = date.getFullYear(); + stateParams.month = date.getMonth() + 1; + + this.linkHelper.goInSite(navCtrl, 'AddonCalendarIndexPage', stateParams, siteId); // @todo: Add checkMenu param. + + } else if (params.view == 'day') { + // Daily view, open the page. + const stateParams: any = { + courseId: params.course + }, + timestamp = params.time ? params.time * 1000 : Date.now(); + + const date = new Date(timestamp); + stateParams.year = date.getFullYear(); + stateParams.month = date.getMonth() + 1; + stateParams.day = date.getDate(); + + this.linkHelper.goInSite(navCtrl, 'AddonCalendarDayPage', stateParams, siteId); + + } else if (params.view == 'upcoming' || params.view == 'upcoming_mini') { + // Upcoming view, open the calendar tab. + const stateParams: any = { + courseId: params.course, + upcoming: true, + }; + + this.linkHelper.goInSite(navCtrl, 'AddonCalendarIndexPage', stateParams, siteId); // @todo: Add checkMenu param. + + } + } + }]; + } + + /** + * Check if the handler is enabled for a certain site (site + user) and a URL. + * If not defined, defaults to true. + * + * @param {string} siteId The site ID. + * @param {string} url The URL to treat. + * @param {any} params The params of the URL. E.g. 'mysite.com?id=1' -> {id: 1} + * @param {number} [courseId] Course ID related to the URL. Optional but recommended. + * @return {boolean|Promise} Whether the handler is enabled for the URL and site. + */ + isEnabled(siteId: string, url: string, params: any, courseId?: number): boolean | Promise { + if (params.view && this.SUPPORTED_VIEWS.indexOf(params.view) == -1) { + // This type of view isn't supported in the app. + return false; + } + + return this.calendarProvider.isDisabled(siteId).then((disabled) => { + if (disabled) { + return false; + } + + return this.calendarProvider.canViewMonth(siteId); + }); + } +} diff --git a/src/providers/utils/url.ts b/src/providers/utils/url.ts index 3035f53c8..70bd15d55 100644 --- a/src/providers/utils/url.ts +++ b/src/providers/utils/url.ts @@ -44,6 +44,17 @@ export class CoreUrlUtilsProvider { return url; } + /** + * Given a URL and a text, return an HTML link. + * + * @param {string} url URL. + * @param {string} text Text of the link. + * @return {string} Link. + */ + buildLink(url: string, text: string): string { + return '
' + text + ''; + } + /** * Extracts the parameters from a URL and stores them in an object. *