forked from EVOgeek/Vmeda.Online
		
	MOBILE-3021 calendar: Support links to calendar
This commit is contained in:
		
							parent
							
								
									083ca7cd7e
								
							
						
					
					
						commit
						f07d6e1df7
					
				| @ -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(); | ||||
|  | ||||
| @ -40,7 +40,7 @@ | ||||
|                 <div class="hidden-phone addon-calendar-day-events"> | ||||
|                     <ng-container *ngFor="let event of day.filteredEvents | slice:0:4; let index = index"> | ||||
|                         <p *ngIf="index < 3 || day.filteredEvents.length == 4" class="addon-calendar-event" (click)="eventClicked(event)"> | ||||
|                             <span class="calendar_event_type calendar_event_{{event.eventtype}}"></span> | ||||
|                             <span class="calendar_event_type calendar_event_{{event.formattedType}}"></span> | ||||
|                             <ion-icon *ngIf="event.offline && !event.deleted" name="time"></ion-icon> | ||||
|                             <ion-icon *ngIf="event.deleted" name="trash"></ion-icon> | ||||
|                             {{ event.timestart * 1000 | coreFormatDate: timeFormat }} | ||||
|  | ||||
| @ -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])); | ||||
|                     } | ||||
|                 } | ||||
|             }); | ||||
|         }); | ||||
|  | ||||
| @ -8,7 +8,7 @@ | ||||
|                 <img *ngIf="event.moduleIcon" src="{{event.moduleIcon}}" item-start class="core-module-icon"> | ||||
|                 <core-icon *ngIf="event.icon && !event.moduleIcon" [name]="event.icon" item-start></core-icon> | ||||
|                 <h2><core-format-text [text]="event.name"></core-format-text></h2> | ||||
|                 <p [innerHTML]="event.formattedtime"></p> | ||||
|                 <p><core-format-text [text]="event.formattedtime"></core-format-text></p> | ||||
|                 <ion-note *ngIf="event.offline && !event.deleted" item-end> | ||||
|                     <ion-icon name="time"></ion-icon> | ||||
|                     <span text-wrap>{{ 'core.notsent' | translate }}</span> | ||||
|  | ||||
| @ -146,6 +146,8 @@ export class AddonCalendarUpcomingEventsComponent implements OnInit, OnChanges, | ||||
|     fetchEvents(): Promise<any> { | ||||
|         // 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); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -49,7 +49,7 @@ | ||||
|                 <img *ngIf="event.moduleIcon" src="{{event.moduleIcon}}" item-start class="core-module-icon"> | ||||
|                 <core-icon *ngIf="event.icon && !event.moduleIcon" [name]="event.icon" item-start></core-icon> | ||||
|                 <h2><core-format-text [text]="event.name"></core-format-text></h2> | ||||
|                 <p [innerHTML]="event.formattedtime"></p> | ||||
|                 <p><core-format-text [text]="event.formattedtime"></core-format-text></p> | ||||
|                 <ion-note *ngIf="event.offline && !event.deleted" item-end> | ||||
|                     <ion-icon name="time"></ion-icon> | ||||
|                     <span text-wrap>{{ 'core.notsent' | translate }}</span> | ||||
|  | ||||
| @ -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<any> { | ||||
|         // 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); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -29,18 +29,11 @@ | ||||
|                 <ion-item text-wrap> | ||||
|                     <core-icon *ngIf="event.icon && !event.moduleIcon" [name]="event.icon" item-start></core-icon> | ||||
|                     <h2><core-format-text [text]="event.name"></core-format-text></h2> | ||||
|                     <p><core-format-text [text]="event.formattedtime"></core-format-text></p> | ||||
|                     <ion-note item-end *ngIf="event.deleted"> | ||||
|                         <ion-icon name="trash"></ion-icon> {{ 'core.deletedoffline' | translate }} | ||||
|                     </ion-note> | ||||
|                 </ion-item> | ||||
|                 <ion-item text-wrap> | ||||
|                     <h2>{{ 'addon.calendar.eventstarttime' | translate}}</h2> | ||||
|                     <p>{{ event.timestart * 1000 | coreFormatDate }}</p> | ||||
|                 </ion-item> | ||||
|                 <ion-item text-wrap *ngIf="event.timeduration > 0"> | ||||
|                     <h2>{{ 'addon.calendar.eventendtime' | translate}}</h2> | ||||
|                     <p>{{ (event.timestart + event.timeduration) * 1000 | coreFormatDate }}</p> | ||||
|                 </ion-item> | ||||
|                 <a ion-item text-wrap *ngIf="courseName" [href]="courseUrl" core-link capture="true"> | ||||
|                     <h2>{{ 'core.course' | translate}}</h2> | ||||
|                     <p><core-format-text [text]="courseName"></core-format-text></p> | ||||
|  | ||||
| @ -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); | ||||
|  | ||||
| @ -28,7 +28,7 @@ | ||||
|         <ion-icon name="warning"></ion-icon> {{ 'core.hasdatatosync' | translate:{$a: 'addon.calendar.calendar' | translate} }} | ||||
|     </ion-card> | ||||
| 
 | ||||
|     <addon-calendar-calendar [hidden]="!showCalendar" [courseId]="courseId" [categoryId]="categoryId" (onEventClicked)="gotoEvent($event)" (onDayClicked)="gotoDay($event)"></addon-calendar-calendar> | ||||
|     <addon-calendar-calendar [hidden]="!showCalendar" [initialYear]="year" [initialMonth]="month" [courseId]="courseId" [categoryId]="categoryId" (onEventClicked)="gotoEvent($event)" (onDayClicked)="gotoDay($event)"></addon-calendar-calendar> | ||||
| 
 | ||||
|     <addon-calendar-upcoming-events *ngIf="loadUpcoming" [hidden]="showCalendar" [courseId]="courseId" [categoryId]="categoryId" (onEventClicked)="gotoEvent($event)"></addon-calendar-upcoming-events> | ||||
| 
 | ||||
|  | ||||
| @ -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) => { | ||||
|  | ||||
| @ -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); | ||||
|             })); | ||||
| 
 | ||||
|  | ||||
| @ -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<string>} 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<string> { | ||||
| 
 | ||||
|         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 + ' <strong>»</strong> ' + dayEnd + timeEnd; | ||||
|                 } else { | ||||
|                     // The event starts in the future, print both days.
 | ||||
|                 return Promise.all(promises).then(() => { | ||||
|                     return dayStart + timeStart + ' <strong>»</strong> ' + 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<string>} Promise resolved with the URL.x | ||||
|      */ | ||||
|     getViewUrl(view: string, time?: number, courseId?: string, siteId?: string): Promise<string> { | ||||
|         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. | ||||
|      * | ||||
|  | ||||
| @ -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; | ||||
|  | ||||
							
								
								
									
										113
									
								
								src/addon/calendar/providers/view-link-handler.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										113
									
								
								src/addon/calendar/providers/view-link-handler.ts
									
									
									
									
									
										Normal file
									
								
							| @ -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<CoreContentLinksAction[]>} List of (or promise resolved with list of) actions. | ||||
|      */ | ||||
|     getActions(siteIds: string[], url: string, params: any, courseId?: number): | ||||
|             CoreContentLinksAction[] | Promise<CoreContentLinksAction[]> { | ||||
|         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<boolean>} Whether the handler is enabled for the URL and site. | ||||
|      */ | ||||
|     isEnabled(siteId: string, url: string, params: any, courseId?: number): boolean | Promise<boolean> { | ||||
|         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); | ||||
|         }); | ||||
|     } | ||||
| } | ||||
| @ -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 '<a href="' + url + '">' + text + '</a>'; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Extracts the parameters from a URL and stores them in an object. | ||||
|      * | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user