NOBILE-3087 calendar: Allow navigating to all days and months in offline
parent
de1207f8be
commit
56d8aba3b4
|
@ -23,6 +23,7 @@ import { AddonCalendarProvider } from '../../providers/calendar';
|
|||
import { AddonCalendarHelperProvider } from '../../providers/helper';
|
||||
import { AddonCalendarOfflineProvider } from '../../providers/calendar-offline';
|
||||
import { CoreCoursesProvider } from '@core/courses/providers/courses';
|
||||
import { CoreAppProvider } from '@providers/app';
|
||||
|
||||
/**
|
||||
* Component that displays a calendar.
|
||||
|
@ -70,7 +71,8 @@ export class AddonCalendarCalendarComponent implements OnInit, OnChanges, OnDest
|
|||
private domUtils: CoreDomUtilsProvider,
|
||||
private timeUtils: CoreTimeUtilsProvider,
|
||||
private utils: CoreUtilsProvider,
|
||||
private coursesProvider: CoreCoursesProvider) {
|
||||
private coursesProvider: CoreCoursesProvider,
|
||||
private appProvider: CoreAppProvider) {
|
||||
|
||||
this.currentSiteId = sitesProvider.getCurrentSiteId();
|
||||
|
||||
|
@ -184,8 +186,14 @@ export class AddonCalendarCalendarComponent implements OnInit, OnChanges, OnDest
|
|||
*/
|
||||
fetchEvents(): Promise<any> {
|
||||
// Don't pass courseId and categoryId, we'll filter them locally.
|
||||
return this.calendarProvider.getMonthlyEvents(this.year, this.month).then((result) => {
|
||||
|
||||
return this.calendarProvider.getMonthlyEvents(this.year, this.month).catch((error) => {
|
||||
if (!this.appProvider.isOnline()) {
|
||||
// Allow navigating to non-cached months in offline (behave as if using emergency cache).
|
||||
return this.calendarHelper.getOfflineMonthWeeks(this.year, this.month);
|
||||
} else {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
}).then((result) => {
|
||||
// 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).getTime(), 'core.strftimemonthyear');
|
||||
|
||||
|
|
|
@ -282,7 +282,14 @@ 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) => {
|
||||
return this.calendarProvider.getDayEvents(this.year, this.month, this.day).catch((error) => {
|
||||
if (!this.appProvider.isOnline()) {
|
||||
// Allow navigating to non-cached days in offline (behave as if using emergency cache).
|
||||
return Promise.resolve({ events: [] });
|
||||
} else {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
}).then((result) => {
|
||||
const promises = [];
|
||||
|
||||
// Calculate the period name. We don't use the one in result because it's in server's language.
|
||||
|
|
|
@ -43,6 +43,7 @@ export class AddonCalendarProvider {
|
|||
static DEFAULT_NOTIFICATION_TIME_CHANGED = 'AddonCalendarDefaultNotificationTimeChangedEvent';
|
||||
static DEFAULT_NOTIFICATION_TIME_SETTING = 'mmaCalendarDefaultNotifTime';
|
||||
static DEFAULT_NOTIFICATION_TIME = 60;
|
||||
static STARTING_WEEK_DAY = 'addon_calendar_starting_week_day';
|
||||
static NEW_EVENT_EVENT = 'addon_calendar_new_event';
|
||||
static NEW_EVENT_DISCARDED_EVENT = 'addon_calendar_new_event_discarded';
|
||||
static EDIT_EVENT_EVENT = 'addon_calendar_edit_event';
|
||||
|
@ -1198,6 +1199,11 @@ export class AddonCalendarProvider {
|
|||
});
|
||||
});
|
||||
|
||||
// Store starting week day preference, we need it in offline to show months that are not in cache.
|
||||
if (this.appProvider.isOnline()) {
|
||||
this.configProvider.set(AddonCalendarProvider.STARTING_WEEK_DAY, response.daynames[0].dayno);
|
||||
}
|
||||
|
||||
return response;
|
||||
});
|
||||
});
|
||||
|
|
|
@ -18,6 +18,7 @@ import { CoreSitesProvider } from '@providers/sites';
|
|||
import { CoreCourseProvider } from '@core/course/providers/course';
|
||||
import { AddonCalendarProvider } from './calendar';
|
||||
import { CoreConstants } from '@core/constants';
|
||||
import { CoreConfigProvider } from '@providers/config';
|
||||
import { CoreUtilsProvider } from '@providers/utils/utils';
|
||||
import * as moment from 'moment';
|
||||
|
||||
|
@ -40,6 +41,7 @@ export class AddonCalendarHelperProvider {
|
|||
private courseProvider: CoreCourseProvider,
|
||||
private sitesProvider: CoreSitesProvider,
|
||||
private calendarProvider: AddonCalendarProvider,
|
||||
private configProvider: CoreConfigProvider,
|
||||
private utils: CoreUtilsProvider) {
|
||||
this.logger = logger.getInstance('AddonCalendarHelperProvider');
|
||||
}
|
||||
|
@ -191,6 +193,66 @@ export class AddonCalendarHelperProvider {
|
|||
return year + '#' + month;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get weeks of a month in offline (with no events).
|
||||
*
|
||||
* The result has the same structure than getMonthlyEvents, but it only contains fields that are actually used by the app.
|
||||
*
|
||||
* @param {number} year Year to get.
|
||||
* @param {number} month Month to get.
|
||||
* @param {string} [siteId] Site ID. If not defined, current site.
|
||||
* @return {Promise<any>} Promise resolved with the response.
|
||||
*/
|
||||
getOfflineMonthWeeks(year: number, month: number, siteId?: string): Promise<any> {
|
||||
return this.sitesProvider.getSite(siteId).then((site) => {
|
||||
// Get starting week day user preference, fallback to site configuration.
|
||||
const startWeekDay = site.getStoredConfig('calendar_startwday');
|
||||
|
||||
return this.configProvider.get(AddonCalendarProvider.STARTING_WEEK_DAY, startWeekDay);
|
||||
}).then((startWeekDay) => {
|
||||
const today = moment();
|
||||
const isCurrentMonth = today.year() == year && today.month() == month - 1;
|
||||
const weeks = [];
|
||||
|
||||
let date = moment({year, month: month - 1, date: 1});
|
||||
for (let mday = 1; mday <= date.daysInMonth(); mday++) {
|
||||
date = moment({year, month: month - 1, date: mday});
|
||||
|
||||
// Add new week and calculate prepadding.
|
||||
if (!weeks.length || date.day() == startWeekDay) {
|
||||
const prepaddingLength = (date.day() - startWeekDay + 7) % 7;
|
||||
const prepadding = [];
|
||||
for (let i = 0; i < prepaddingLength; i++) {
|
||||
prepadding.push(i);
|
||||
}
|
||||
weeks.push({ prepadding, postpadding: [], days: []});
|
||||
}
|
||||
|
||||
// Calculate postpadding of last week.
|
||||
if (mday == date.daysInMonth()) {
|
||||
const postpaddingLength = (startWeekDay - date.day() + 6) % 7;
|
||||
const postpadding = [];
|
||||
for (let i = 0; i < postpaddingLength; i++) {
|
||||
postpadding.push(i);
|
||||
}
|
||||
weeks[weeks.length - 1].postpadding = postpadding;
|
||||
}
|
||||
|
||||
// Add day to current week.
|
||||
weeks[weeks.length - 1].days.push({
|
||||
events: [],
|
||||
hasevents: false,
|
||||
mday: date.date(),
|
||||
isweekend: date.day() == 0 || date.day() == 6,
|
||||
istoday: isCurrentMonth && today.date() == date.date(),
|
||||
calendareventtypes: [],
|
||||
});
|
||||
}
|
||||
|
||||
return {weeks, daynames: [{dayno: startWeekDay}]};
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the data of an event has changed.
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue