/** * mobile.js - Base mobile application logic. * * Copyright 2010-2017 Horde LLC (http://www.horde.org/) * * See the enclosed file COPYING for license information (GPL). If you * did not receive this file, see http://www.horde.org/licenses/gpl. * * @author Michael J. Rubinsky * @author Jan Schneider * @category Horde * @license http://www.horde.org/licenses/gpl GPL * @package Kronolith */ var KronolithMobile = { /** * List of calendars we are displaying */ calendars: [], /** * List of calendars that are currently loaded for the current view */ loadedCalendars: [], /** * Event cache */ ecache: {}, cacheStart: null, cacheEnd: null, deferHash: {}, viewRan: false, /** * The currently displayed view */ view: 'day', /** * The currently selected date */ date: null, /** * Temporary fix for pages not firing pagebeforecreate events properly */ haveOverview: false, /** * Load all events between start and end time. * * @param Date firstDay * @param Date lastDay * @param string view The view we are loading for (month, day) */ loadEvents: function(firstDay, lastDay, view) { var dates = [firstDay, lastDay], loading = false; // Clear out the loaded cal cache KronolithMobile.loadedCalendars = []; KronolithMobile.clearView(view); KronolithMobile.viewRan = false; $.each(KronolithMobile.calendars, function(key, cal) { var startDay = dates[0].clone(), endDay = dates[1].clone(), cals = KronolithMobile.ecache[cal[0]], c; if (typeof cals != 'undefined' && typeof cals[cal[1]] != 'undefined') { cals = cals[cal[1]]; c = cals[startDay.dateString()]; while (typeof c != 'undefined' && startDay.isBefore(endDay)) { if (view == 'day') { KronolithMobile.insertEvents([startDay, startDay], view, cal.join('|')); } startDay.addDays(1); c = cals[startDay.dateString()]; } c = cals[endDay.dateString()]; while (typeof c != 'undefined' && !startDay.isAfter(endDay)) { if (view == 'day') { KronolithMobile.insertEvents([endDay, endDay], view, cal.join('|')); } endDay.addDays(-1); c = cals[endDay.dateString()]; } if (startDay.compareTo(endDay) > 0) { KronolithMobile.loadedCalendars.push(cal.join('|')); return; } } var start = startDay.dateString(), end = endDay.dateString(); loading = true; HordeMobile.doAction('listEvents', { 'start': start, 'end': end, 'cal': cal.join('|'), 'view': view, 'sig': start + end + (Math.random() + '').slice(2) }, KronolithMobile.loadEventsCallback ); }); if (!loading && view == 'overview') { KronolithMobile.insertEvents([firstDay, lastDay], view); } }, /** * Sort a collection of events as returned from the ecache */ sortEvents: function(events) { var e = []; // Need a native array to sort. $.each(events, function(id, event) { e.push(event); }); return e.sort(function(a, b) { sortA = a.sort; sortB = b.sort; return (sortA < sortB) ? -1 : (sortA > sortB) ? 1 : 0; }); }, /** * Callback for the loadEvents AJAX request. * * @param object data The ajax response. */ loadEventsCallback: function(data) { var start = KronolithMobile.parseDate(data.sig.substr(0, 8)), end = KronolithMobile.parseDate(data.sig.substr(8, 8)), dates = [start, end], view = data.view; KronolithMobile.storeCache(data.events, data.cal, dates, true); KronolithMobile.loadedCalendars.push(data.cal); KronolithMobile.insertEvents(dates, view, data.cal); }, /** * Inserts events into current view. * For Day view, builds a new listview and attaches to the DOM. * For Month view, hightlights dates with events. */ insertEvents: function(dates, view, cal) { var key = dates[0].dateString() + dates[1].dateString() + view + cal, d = [dates[0].clone(), dates[1].clone()], date, events, list, day; // Make sure all calendars are loaded before rendering the view. // @TODO: Implement LIFO queue as in kronolith.js if (KronolithMobile.loadedCalendars.length != KronolithMobile.calendars.length) { if (KronolithMobile.deferHash[key]) { return; } else { KronolithMobile.deferHash[key] = window.setTimeout(function() { KronolithMobile.insertEvents(d, view, cal); }, 0); return; } } if (KronolithMobile.deferHash[key]) { window.clearTimeout(KronolithMobile.deferHash[key]); KronolithMobile.deferHash[key] = false; } KronolithMobile.running = true; switch (view) { case 'day': if (!KronolithMobile.viewRan) { KronolithMobile.viewRan = true; date = d[0].dateString(); events = KronolithMobile.getCacheForDate(date); events = KronolithMobile.sortEvents(events); list = $('