[IMP] calendar: remove /calendar/notify RPC done every 5 minutes

Basicaly, do this RPC once, at webclient startup, to get the next notification.
Do the RPC again when the notification is displayed to get the next one.
When an event with alarm is created, edited or removed, trigger an event on the
bus for all involved users (the attendees) with an update of their next
calendar notification.
This commit is contained in:
Aaron Bohy
2016-06-27 15:30:45 +02:00
parent d9cc893dbc
commit 488e9f299d
4 changed files with 162 additions and 85 deletions
+100 -55
View File
@@ -324,8 +324,17 @@ class res_partner(osv.Model):
class calendar_alarm_manager(osv.AbstractModel): class calendar_alarm_manager(osv.AbstractModel):
_name = 'calendar.alarm_manager' _name = 'calendar.alarm_manager'
def get_next_potential_limit_alarm(self, cr, uid, seconds, notif=True, mail=True, partner_id=None, context=None): def get_next_potential_limit_alarm(self, cr, uid, alarm_type, seconds=None, partner_id=None, context=None):
res = {} res = {}
delta_request = """
SELECT
rel.calendar_event_id, max(alarm.duration_minutes) AS max_delta,min(alarm.duration_minutes) AS min_delta
FROM
calendar_alarm_calendar_event_rel AS rel
LEFT JOIN calendar_alarm AS alarm ON alarm.id = rel.calendar_alarm_id
WHERE alarm.type = %s
GROUP BY rel.calendar_event_id
"""
base_request = """ base_request = """
SELECT SELECT
cal.id, cal.id,
@@ -344,16 +353,7 @@ class calendar_alarm_manager(osv.AbstractModel):
cal.rrule AS rule cal.rrule AS rule
FROM FROM
calendar_event AS cal calendar_event AS cal
RIGHT JOIN RIGHT JOIN calcul_delta ON calcul_delta.calendar_event_id = cal.id
(
SELECT
rel.calendar_event_id, max(alarm.duration_minutes) AS max_delta,min(alarm.duration_minutes) AS min_delta
FROM
calendar_alarm_calendar_event_rel AS rel
LEFT JOIN calendar_alarm AS alarm ON alarm.id = rel.calendar_alarm_id
WHERE alarm.type in %s
GROUP BY rel.calendar_event_id
) AS calcul_delta ON calcul_delta.calendar_event_id = cal.id
""" """
filter_user = """ filter_user = """
@@ -361,28 +361,36 @@ class calendar_alarm_manager(osv.AbstractModel):
AND part_rel.res_partner_id = %s AND part_rel.res_partner_id = %s
""" """
#Add filter on type # Add filter on alarm type
type_to_read = () tuple_params = (alarm_type,)
if notif:
type_to_read += ('notification',)
if mail:
type_to_read += ('email',)
tuple_params = (type_to_read,) # Add filter on partner_id
# ADD FILTER ON PARTNER_ID
if partner_id: if partner_id:
base_request += filter_user base_request += filter_user
tuple_params += (partner_id, ) tuple_params += (partner_id, )
#Add filter on hours # Upper bound on first_alarm of requested events
tuple_params += (seconds,) first_alarm_max_value = ""
if seconds is None:
# first alarm in the future + 3 minutes if there is one, now otherwise
first_alarm_max_value = """
COALESCE((SELECT MIN(cal.start - interval '1' minute * calcul_delta.max_delta)
FROM calendar_event cal
RIGHT JOIN calcul_delta ON calcul_delta.calendar_event_id = cal.id
WHERE cal.start - interval '1' minute * calcul_delta.max_delta > now() at time zone 'utc'
) + interval '3' minute, now() at time zone 'utc')"""
else:
# now + given seconds
first_alarm_max_value = "(now() at time zone 'utc' + interval '%s' second )"
tuple_params += (seconds,)
cr.execute("""SELECT * cr.execute("""
WITH calcul_delta AS (%s)
SELECT *
FROM ( %s WHERE cal.active = True ) AS ALL_EVENTS FROM ( %s WHERE cal.active = True ) AS ALL_EVENTS
WHERE ALL_EVENTS.first_alarm < (now() at time zone 'utc' + interval '%%s' second ) WHERE ALL_EVENTS.first_alarm < %s
AND ALL_EVENTS.last_event_date > (now() at time zone 'utc') AND ALL_EVENTS.last_event_date > (now() at time zone 'utc')
""" % base_request, tuple_params) """ % (delta_request, base_request, first_alarm_max_value), tuple_params)
for event_id, first_alarm, last_alarm, first_meeting, last_meeting, min_duration, max_duration, rule in cr.fetchall(): for event_id, first_alarm, last_alarm, first_meeting, last_meeting, min_duration, max_duration, rule in cr.fetchall():
res[event_id] = { res[event_id] = {
@@ -398,28 +406,20 @@ class calendar_alarm_manager(osv.AbstractModel):
return res return res
def do_check_alarm_for_one_date(self, cr, uid, one_date, event, event_maxdelta, in_the_next_X_seconds, after=False, notif=True, mail=True, missing=False, context=None): def do_check_alarm_for_one_date(self, cr, uid, one_date, event, event_maxdelta, in_the_next_X_seconds, alarm_type, after=False, missing=False, context=None):
# one_date: date of the event to check (not the same that in the event browse if recurrent) # one_date: date of the event to check (not the same that in the event browse if recurrent)
# event: Event browse record # event: Event browse record
# event_maxdelta: biggest duration from alarms for this event # event_maxdelta: biggest duration from alarms for this event
# in_the_next_X_seconds: looking in the future (in seconds) # in_the_next_X_seconds: looking in the future (in seconds)
# alarm_type: the type of alarm we are looking for ('notification' or 'email')
# after: if not False: will return alert if after this date (date as string - todo: change in master) # after: if not False: will return alert if after this date (date as string - todo: change in master)
# missing: if not False: will return alert even if we are too late # missing: if not False: will return alert even if we are too late
# notif: Looking for type notification
# mail: looking for type email
res = [] res = []
# TODO: remove event_maxdelta and if using it
# TODO: replace notif and email in master by alarm_type + remove event_maxdelta and if using it
alarm_type = []
if notif:
alarm_type.append('notification')
if mail:
alarm_type.append('email')
if one_date - timedelta(minutes=(missing and 0 or event_maxdelta)) < datetime.now() + timedelta(seconds=in_the_next_X_seconds): # if an alarm is possible for this date if one_date - timedelta(minutes=(missing and 0 or event_maxdelta)) < datetime.now() + timedelta(seconds=in_the_next_X_seconds): # if an alarm is possible for this date
for alarm in event.alarm_ids: for alarm in event.alarm_ids:
if alarm.type in alarm_type and \ if alarm.type == alarm_type and \
one_date - timedelta(minutes=(missing and 0 or alarm.duration_minutes)) < datetime.now() + timedelta(seconds=in_the_next_X_seconds) and \ one_date - timedelta(minutes=(missing and 0 or alarm.duration_minutes)) < datetime.now() + timedelta(seconds=in_the_next_X_seconds) and \
(not after or one_date - timedelta(minutes=alarm.duration_minutes) > openerp.fields.Datetime.from_string(after)): (not after or one_date - timedelta(minutes=alarm.duration_minutes) > openerp.fields.Datetime.from_string(after)):
alert = { alert = {
@@ -456,7 +456,7 @@ class calendar_alarm_manager(osv.AbstractModel):
cron_interval = cron.interval_number * interval_to_second[cron.interval_type] cron_interval = cron.interval_number * interval_to_second[cron.interval_type]
all_events = self.get_next_potential_limit_alarm(cr, uid, cron_interval, notif=False, context=context) all_events = self.get_next_potential_limit_alarm(cr, uid, 'email', seconds=cron_interval, context=context)
for curEvent in self.pool.get('calendar.event').browse(cr, uid, all_events.keys(), context=context): for curEvent in self.pool.get('calendar.event').browse(cr, uid, all_events.keys(), context=context):
max_delta = all_events[curEvent.id]['max_duration'] max_delta = all_events[curEvent.id]['max_duration']
@@ -466,7 +466,7 @@ class calendar_alarm_manager(osv.AbstractModel):
last_found = False last_found = False
for one_date in self.pool.get('calendar.event').get_recurrent_date_by_event(cr, uid, curEvent, context=context): for one_date in self.pool.get('calendar.event').get_recurrent_date_by_event(cr, uid, curEvent, context=context):
in_date_format = one_date.replace(tzinfo=None) in_date_format = one_date.replace(tzinfo=None)
last_found = self.do_check_alarm_for_one_date(cr, uid, in_date_format, curEvent, max_delta, 0, after=last_notif_mail, notif=False, missing=True, context=context) last_found = self.do_check_alarm_for_one_date(cr, uid, in_date_format, curEvent, max_delta, 0, 'email', after=last_notif_mail, missing=True, context=context)
for alert in last_found: for alert in last_found:
self.do_mail_reminder(cr, uid, alert, context=context) self.do_mail_reminder(cr, uid, alert, context=context)
at_least_one = True # if it's the first alarm for this recurrent event at_least_one = True # if it's the first alarm for this recurrent event
@@ -474,21 +474,20 @@ class calendar_alarm_manager(osv.AbstractModel):
break break
else: else:
in_date_format = datetime.strptime(curEvent.start, DEFAULT_SERVER_DATETIME_FORMAT) in_date_format = datetime.strptime(curEvent.start, DEFAULT_SERVER_DATETIME_FORMAT)
last_found = self.do_check_alarm_for_one_date(cr, uid, in_date_format, curEvent, max_delta, 0, after=last_notif_mail, notif=False, missing=True, context=context) last_found = self.do_check_alarm_for_one_date(cr, uid, in_date_format, curEvent, max_delta, 0, 'email', after=last_notif_mail, missing=True, context=context)
for alert in last_found: for alert in last_found:
self.do_mail_reminder(cr, uid, alert, context=context) self.do_mail_reminder(cr, uid, alert, context=context)
icp.set_param(cr, SUPERUSER_ID, 'calendar.last_notif_mail', now) icp.set_param(cr, SUPERUSER_ID, 'calendar.last_notif_mail', now)
def get_next_notif(self, cr, uid, context=None): def get_next_notif(self, cr, uid, context=None):
ajax_check_every_seconds = 300
partner = self.pool['res.users'].read(cr, SUPERUSER_ID, uid, ['partner_id', 'calendar_last_notif_ack'], context=context) partner = self.pool['res.users'].read(cr, SUPERUSER_ID, uid, ['partner_id', 'calendar_last_notif_ack'], context=context)
all_notif = [] all_notif = []
if not partner: if not partner:
return [] return []
all_events = self.get_next_potential_limit_alarm(cr, uid, ajax_check_every_seconds, partner_id=partner['partner_id'][0], mail=False, context=context) all_events = self.get_next_potential_limit_alarm(cr, uid, 'notification', partner_id=partner['partner_id'][0], context=context)
time_limit = 3600 * 24 # return alarms of the next 24 hours
for event in all_events: # .values() for event in all_events: # .values()
max_delta = all_events[event]['max_duration'] max_delta = all_events[event]['max_duration']
curEvent = self.pool.get('calendar.event').browse(cr, uid, event, context=context) curEvent = self.pool.get('calendar.event').browse(cr, uid, event, context=context)
@@ -497,7 +496,7 @@ class calendar_alarm_manager(osv.AbstractModel):
LastFound = False LastFound = False
for one_date in self.pool.get("calendar.event").get_recurrent_date_by_event(cr, uid, curEvent, context=context): for one_date in self.pool.get("calendar.event").get_recurrent_date_by_event(cr, uid, curEvent, context=context):
in_date_format = one_date.replace(tzinfo=None) in_date_format = one_date.replace(tzinfo=None)
LastFound = self.do_check_alarm_for_one_date(cr, uid, in_date_format, curEvent, max_delta, ajax_check_every_seconds, after=partner['calendar_last_notif_ack'], mail=False, context=context) LastFound = self.do_check_alarm_for_one_date(cr, uid, in_date_format, curEvent, max_delta, time_limit, 'notification', after=partner['calendar_last_notif_ack'], context=context)
if LastFound: if LastFound:
for alert in LastFound: for alert in LastFound:
all_notif.append(self.do_notif_reminder(cr, uid, alert, context=context)) all_notif.append(self.do_notif_reminder(cr, uid, alert, context=context))
@@ -507,7 +506,7 @@ class calendar_alarm_manager(osv.AbstractModel):
break break
else: else:
in_date_format = datetime.strptime(curEvent.start, DEFAULT_SERVER_DATETIME_FORMAT) in_date_format = datetime.strptime(curEvent.start, DEFAULT_SERVER_DATETIME_FORMAT)
LastFound = self.do_check_alarm_for_one_date(cr, uid, in_date_format, curEvent, max_delta, ajax_check_every_seconds, after=partner['calendar_last_notif_ack'], mail=False, context=context) LastFound = self.do_check_alarm_for_one_date(cr, uid, in_date_format, curEvent, max_delta, time_limit, 'notification', after=partner['calendar_last_notif_ack'], context=context)
if LastFound: if LastFound:
for alert in LastFound: for alert in LastFound:
all_notif.append(self.do_notif_reminder(cr, uid, alert, context=context)) all_notif.append(self.do_notif_reminder(cr, uid, alert, context=context))
@@ -536,9 +535,8 @@ class calendar_alarm_manager(osv.AbstractModel):
def do_notif_reminder(self, cr, uid, alert, context=None): def do_notif_reminder(self, cr, uid, alert, context=None):
alarm = self.pool['calendar.alarm'].browse(cr, uid, alert['alarm_id'], context=context) alarm = self.pool['calendar.alarm'].browse(cr, uid, alert['alarm_id'], context=context)
event = self.pool['calendar.event'].browse(cr, uid, alert['event_id'], context=context)
if alarm.type == 'notification': if alarm.type == 'notification':
event = self.pool['calendar.event'].browse(cr, uid, alert['event_id'], context=context)
message = event.display_time message = event.display_time
delta = alert['notify_at'] - datetime.now() delta = alert['notify_at'] - datetime.now()
@@ -552,6 +550,18 @@ class calendar_alarm_manager(osv.AbstractModel):
'notify_at': alert['notify_at'].strftime(DEFAULT_SERVER_DATETIME_FORMAT), 'notify_at': alert['notify_at'].strftime(DEFAULT_SERVER_DATETIME_FORMAT),
} }
def notify_next_alarm(self, cr, uid, partner_ids, context=None):
""" Sends through the bus the next alarm of given partners """
notifications = []
user_obj = self.pool['res.users']
user_ids = user_obj.search(cr, uid, [('partner_id', 'in', tuple(partner_ids))], context=context)
users = user_obj.browse(cr, uid, user_ids, context=context)
for user in users:
notif = self.get_next_notif(cr, user.id, context=context)
notifications.append([(cr.dbname, 'calendar.alarm', user.partner_id.id), notif])
if len(notifications) > 0:
self.pool['bus.bus'].sendmany(cr, uid, notifications)
class calendar_alarm(osv.Model): class calendar_alarm(osv.Model):
_name = 'calendar.alarm' _name = 'calendar.alarm'
@@ -1100,14 +1110,15 @@ class calendar_event(osv.Model):
attendee_ids_to_remove = [] attendee_ids_to_remove = []
if partner_ids_to_remove: if partner_ids_to_remove:
attendee_ids_to_remove = self.pool["calendar.attendee"].search(cr, uid, [('partner_id.id', 'in', partner_ids_to_remove), ('event_id.id', '=', event.id)], context=context) attendee_ids_to_remove = self.pool["calendar.attendee"].search(cr, uid, [('partner_id.id', 'in', partner_ids_to_remove), ('event_id', '=', event.id)], context=context)
if attendee_ids_to_remove: if attendee_ids_to_remove:
self.pool['calendar.attendee'].unlink(cr, uid, attendee_ids_to_remove, context) self.pool['calendar.attendee'].unlink(cr, uid, attendee_ids_to_remove, context)
res[event.id] = { res[event.id] = {
'new_attendee_ids': new_attendees, 'new_attendee_ids': new_attendees,
'old_attendee_ids': all_attendee_ids, 'old_attendee_ids': all_attendee_ids,
'removed_attendee_ids': attendee_ids_to_remove 'removed_attendee_ids': attendee_ids_to_remove,
'removed_partner_ids': partner_ids_to_remove
} }
return res return res
@@ -1566,6 +1577,7 @@ class calendar_event(osv.Model):
ids = [ids] ids = [ids]
values0 = values values0 = values
dont_notify_ctx = dict(context, dont_notify=True) # to prevent multiple notify_next_alarm
# process events one by one # process events one by one
for event_id in ids: for event_id in ids:
@@ -1590,7 +1602,7 @@ class calendar_event(osv.Model):
else: else:
data = self.read(cr, uid, event_id, ['start', 'stop', 'rrule', 'duration']) data = self.read(cr, uid, event_id, ['start', 'stop', 'rrule', 'duration'])
if data.get('rrule'): if data.get('rrule'):
new_ids = [self._detach_one_event(cr, uid, event_id, values, context=None)] new_ids = [self._detach_one_event(cr, uid, event_id, values, context=dont_notify_ctx)]
super(calendar_event, self).write(cr, uid, real_ids, values, context=context) super(calendar_event, self).write(cr, uid, real_ids, values, context=context)
@@ -1603,7 +1615,18 @@ class calendar_event(osv.Model):
attendees_create = False attendees_create = False
if values.get('partner_ids', False): if values.get('partner_ids', False):
attendees_create = self.create_attendees(cr, uid, real_ids + new_ids, context) attendees_create = self.create_attendees(cr, uid, real_ids + new_ids, context=dont_notify_ctx)
# Notify attendees if there is an alarm on the modified event, or if there was an alarm
# that has just been removed, as it might have changed their next event notification
if not context.get('dont_notify'):
event = self.browse(cr, uid, event_id, context=context)
if len(event.alarm_ids) > 0 or values.get('alarm_ids'):
partners_to_notify = set([p.id for p in event.partner_ids])
event_attendees_changes = attendees_create and attendees_create[real_ids[0]]
if event_attendees_changes:
partners_to_notify.update(event_attendees_changes['removed_partner_ids'])
self.pool['calendar.alarm_manager'].notify_next_alarm(cr, uid, partners_to_notify)
if (values.get('start_date') or values.get('start_datetime')) and values.get('active', True): if (values.get('start_date') or values.get('start_datetime')) and values.get('active', True):
for the_id in real_ids + new_ids: for the_id in real_ids + new_ids:
@@ -1629,10 +1652,20 @@ class calendar_event(osv.Model):
res = super(calendar_event, self).create(cr, uid, vals, context=context) res = super(calendar_event, self).create(cr, uid, vals, context=context)
final_date = self._get_recurrency_end_date(cr, uid, res, context=context) dont_notify_context = dict(context, dont_notify=True) # to prevent multiple notify_next_alarm
self.write(cr, uid, [res], {'final_date': final_date}, context=context)
final_date = self._get_recurrency_end_date(cr, uid, res, context=context)
self.write(cr, uid, [res], {'final_date': final_date}, context=dont_notify_context)
self.create_attendees(cr, uid, [res], context=dont_notify_context)
# Notify attendees if there is an alarm on the created event, as it might have changed their
# next event notification
if not context.get('dont_notify'):
event = self.browse(cr, uid, [res], context=context) # remove this when migrating to new API
if len(event.alarm_ids) > 0:
self.pool['calendar.alarm_manager'].notify_next_alarm(cr, uid, [p.id for p in event.partner_ids])
self.create_attendees(cr, uid, [res], context=context)
return res return res
def export_data(self, cr, uid, ids, *args, **kwargs): def export_data(self, cr, uid, ids, *args, **kwargs):
@@ -1723,6 +1756,14 @@ class calendar_event(osv.Model):
ids_to_exclure = [] ids_to_exclure = []
ids_to_unlink = [] ids_to_unlink = []
# Get concerned attendees to notify them if there is an alarm on the unlinked events,
# as it might have changed their next event notification
event_ids = self.search(cr, uid, [('id', 'in', ids), ('alarm_ids', '!=', False)], context=context)
events = self.browse(cr, uid, event_ids, context=context)
partner_ids = set()
for event in events:
partner_ids.update([p.id for p in event.partner_ids])
for event_id in ids: for event_id in ids:
if can_be_deleted and len(str(event_id).split('-')) == 1: # if ID REAL if can_be_deleted and len(str(event_id).split('-')) == 1: # if ID REAL
if self.browse(cr, uid, int(event_id), context).recurrent_id: if self.browse(cr, uid, int(event_id), context).recurrent_id:
@@ -1736,8 +1777,12 @@ class calendar_event(osv.Model):
res = super(calendar_event, self).unlink(cr, uid, ids_to_unlink, context=context) res = super(calendar_event, self).unlink(cr, uid, ids_to_unlink, context=context)
if ids_to_exclure: if ids_to_exclure:
ctx = dict(context, dont_notify=True) # to prevent multiple notify_next_alarm
for id_to_exclure in ids_to_exclure: for id_to_exclure in ids_to_exclure:
res = self.write(cr, uid, id_to_exclure, {'active': False}, context=context) res = self.write(cr, uid, id_to_exclure, {'active': False}, context=ctx)
# Notify the concerned attendees (must be done after removing the events)
self.pool['calendar.alarm_manager'].notify_next_alarm(cr, uid, partner_ids)
return res return res
+1
View File
@@ -1 +1,2 @@
import main import main
import bus
+13
View File
@@ -0,0 +1,13 @@
# -*- coding: utf-8 -*
import openerp
from openerp.http import request
class CalendarBusController(openerp.addons.bus.controllers.main.BusController):
# --------------------------
# Extends BUS Controller Poll
# --------------------------
def _poll(self, dbname, channels, last, options):
if request.session.uid:
channels.append((request.db, 'calendar.alarm', request.env.user.partner_id.id))
return super(CalendarBusController, self)._poll(dbname, channels, last, options)
+48 -30
View File
@@ -1,6 +1,7 @@
odoo.define('base_calendar.base_calendar', function (require) { odoo.define('base_calendar.base_calendar', function (require) {
"use strict"; "use strict";
var bus = require('bus.bus').bus;
var core = require('web.core'); var core = require('web.core');
var CalendarView = require('web_calendar.CalendarView'); var CalendarView = require('web_calendar.CalendarView');
var data = require('web.data'); var data = require('web.data');
@@ -189,43 +190,60 @@ var CalendarNotification = Notification.extend({
}); });
WebClient.include({ WebClient.include({
get_next_notif: function() { display_calendar_notif: function(notifications) {
var self = this; var self = this;
var last_notif_timer = 0;
this.rpc("/calendar/notify", {}, {shadow: true}) // Clear previously set timeouts and destroy currently displayed calendar notifications
.done(function(result) { clearTimeout(this.get_next_calendar_notif_timeout);
_.each(result, function(res) { _.each(this.calendar_notif_timeouts, clearTimeout);
setTimeout(function() { _.each(this.calendar_notif, function(notif) {
// If notification not already displayed, we create and display it (FIXME is this check usefull?) if (!notif.isDestroyed()) {
if(self.$(".eid_" + res.event_id).length === 0) { notif.destroy();
self.notification_manager.display(new CalendarNotification(self.notification_manager, res.title, res.message, res.event_id));
}
}, res.timer * 1000);
});
})
.fail(function(err, ev) {
if(err.code === -32098) {
// Prevent the CrashManager to display an error
// in case of an xhr error not due to a server error
ev.preventDefault();
} }
}); });
this.calendar_notif_timeouts = {};
this.calendar_notif = {};
// For each notification, set a timeout to display it
_.each(notifications, function(notif) {
self.calendar_notif_timeouts[notif.event_id] = setTimeout(function() {
var notification = new CalendarNotification(self.notification_manager, notif.title, notif.message, notif.event_id);
self.notification_manager.display(notification);
self.calendar_notif[notif.event_id] = notification;
}, notif.timer * 1000);
last_notif_timer = Math.max(last_notif_timer, notif.timer);
});
// Set a timeout to get the next notifications when the last one has been displayed
if (last_notif_timer > 0) {
this.get_next_calendar_notif_timeout = setTimeout(this.get_next_calendar_notif.bind(this), last_notif_timer * 1000);
}
}, },
check_notifications: function() { get_next_calendar_notif: function() {
var self = this; this.rpc("/calendar/notify", {}, {shadow: true})
this.get_next_notif(); .done(this.display_calendar_notif.bind(this))
this.intervalNotif = setInterval(function() { .fail(function(err, ev) {
self.get_next_notif(); if(err.code === -32098) {
}, 5 * 60 * 1000); // Prevent the CrashManager to display an error
// in case of an xhr error not due to a server error
ev.preventDefault();
}
});
}, },
show_application: function() { show_application: function() {
return this._super.apply(this, arguments).then(this.check_notifications.bind(this)); // An event is triggered on the bus each time a calendar event with alarm
}, // in which the current user is involved is created, edited or deleted
//Override addons/web/static/src/js/chrome.js this.calendar_notif_timeouts = {};
// FIXME: on_logout is no longer used this.calendar_notif = {};
on_logout: function() { bus.on('notification', this, function (notifications) {
this._super(); _.each(notifications, (function (notification) {
clearInterval(this.intervalNotif); if (notification[0][1] === 'calendar.alarm') {
this.display_calendar_notif(notification[1]);
}
}).bind(this));
});
return this._super.apply(this, arguments).then(this.get_next_calendar_notif.bind(this));
}, },
}); });