Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Popup alarms/reminders don't work with WCAP server (Bugzilla Bug 380423) #2

Open
kewisch opened this issue May 11, 2007 · 27 comments
Open
Labels
enhancement New feature or request

Comments

@kewisch
Copy link
Owner

kewisch commented May 11, 2007

Bugzilla Bug 380423

Date: 2007-05-11T19:56:34+02:00
From: jlarsen@fsu.edu
Assigned To: nobody

Last updated: 2013-05-30T12:38:21+02:00

@kewisch
Copy link
Owner Author

kewisch commented May 11, 2007

Comment 3183118

Date: 2007-05-11 19:56:34 +0200
From: jlarsen@fsu.edu

Set a WCAP network calendar and set an event with alarm. Alarm never goes off.

The remote WCAP server is out of my control and is in beta and having connection issues, but even if remote server is disconnected local calendar knows about event and shows it, so shouldn't alarm be going off?

@kewisch
Copy link
Owner Author

kewisch commented May 11, 2007

Comment 3183215

Date: 2007-05-11 21:44:17 +0200
From: Stefan Sitter [:ssitter] <ssitter@gmail.com>

Hi, do you mixed up some things? Are you using a locale calendar or are you using a remote calendar on a Sun Java System Calendar Server? In the latter case you always need a connection to the server to view/edit/create events.

@kewisch
Copy link
Owner Author

kewisch commented May 11, 2007

Comment 3183229

Date: 2007-05-11 22:03:23 +0200
From: jlarsen@fsu.edu

Using a remote calendar on a Sun Java System Calendar Server. Yea I am connected to the server when I create the event, I can confirm that the event is viewable on my local computer and the remote webpage on the server. The alarm inside thunderbird never fires. I don't know if it has to do with the connection issue (it times out frequently) or what, but seems to me it holds a local cache and should fire from that independent of connection.??

@kewisch
Copy link
Owner Author

kewisch commented May 12, 2007

Comment 3183714

Date: 2007-05-12 15:44:57 +0200
From: @dbo

This feature is currently not implementable, because X-props can't be saved (more specifically replaced) reliably. Right now, if you specify an alarm (and you have defined an email address in your calendar settings), an email notification alarm is set on the server using the respective time offset. I change this bug to RFE, still on my list, of course.

@kewisch
Copy link
Owner Author

kewisch commented Oct 31, 2007

Comment 3356950

Date: 2007-10-31 13:52:56 +0100
From: @dbo

We might head towards a solution for WCAP popup alarms when we have offline support: We could keep the full calendar data (including alarm definitions/dismiss stamps) locally, while we omit those data (e.g. X-prop dismiss stamps) when writing to the server.

@kewisch
Copy link
Owner Author

kewisch commented Feb 27, 2008

Comment 3502100

Date: 2008-02-27 19:49:38 +0100
From: Stefan Sitter [:ssitter] <ssitter@gmail.com>

*** Bug #419871 has been marked as a duplicate of this bug. ***

@kewisch
Copy link
Owner Author

kewisch commented Jun 15, 2008

Comment 3662296

Date: 2008-06-15 18:32:41 +0200
From: Stefan Sitter [:ssitter] <ssitter@gmail.com>

*** Bug #439329 has been marked as a duplicate of this bug. ***

@kewisch
Copy link
Owner Author

kewisch commented Jul 2, 2008

Comment 3688307

Date: 2008-07-02 06:12:27 +0200
From: anil srivastava <anil.srivastava@sun.com>

Is this going to be fixed when the offline support is available with M9 build? The approach suggested by Daniel on 1007-05-12 is the approach Outlook Connector uses for popup alarms too.

@kewisch
Copy link
Owner Author

kewisch commented Jul 2, 2008

Comment 3689119

Date: 2008-07-02 20:25:37 +0200
From: @bshannon

Any solution that allows me to configure the alarm behavior in the server so
that all clients know what alarms to trigger seems fine. If every client
connected to the server presents the alarm, even though I dismiss the alarm
on the one client I'm sitting on front of, that's good enough. Better to get
alarms on every client than alarms on no clients.

@kewisch
Copy link
Owner Author

kewisch commented Jul 7, 2008

Comment 3694131

Date: 2008-07-07 18:52:13 +0200
From: @dbo

(In reply to comment #7)

Is this going to be fixed when the offline support is available with M9 build?
No, we most possibly won't do that for 0.9, but head for a solution storing X-props post 0.9 (because the related server bug is fixed in cs 6.4).

@kewisch
Copy link
Owner Author

kewisch commented Aug 5, 2008

Comment 3728230

Date: 2008-08-05 06:42:47 +0200
From: @kewisch

*** Bug #449166 has been marked as a duplicate of this bug. ***

@kewisch
Copy link
Owner Author

kewisch commented Mar 2, 2009

Comment 3997117

Date: 2009-03-02 21:02:54 +0100
From: Backstage <Backstage@gmx.de>

Following changes will make alarm reminders work with Sun System Calendar Server (WCAP):

Instead of using the X-props you should use the alarmOffset parameter of the calendar event item.

If an alarm is fired and the user selects:
a) dismiss alarm
if(newParent.calendar.type == "wcap")
{
newParent.alarmOffset = null;
}
-----> alarmOffset=null removes the alarm

b) snooze alarm
-----> duration = alarmTime.subtractDate(newEvent.startDate); //newEvent is after has to be after the alarmTime
-----> newEvent.alarmOffset = duration;

@kewisch
Copy link
Owner Author

kewisch commented Mar 2, 2009

Comment 3997126

Date: 2009-03-02 21:06:58 +0100
From: Backstage <Backstage@gmx.de>

Created attachment 364975
calAlarmService.js file with fixed alarm reminder

Attached file: calAlarmService.js (text/plain, 24309 bytes)
Description: calAlarmService.js file with fixed alarm reminder

@kewisch
Copy link
Owner Author

kewisch commented Mar 2, 2009

Comment 3997255

Date: 2009-03-02 22:19:37 +0100
From: @kewisch

So to make them "work", you remove the actual offset? Also, please note that the alarm service will change quite a bit in 1.0pre.

@kewisch
Copy link
Owner Author

kewisch commented Mar 2, 2009

Comment 3997349

Date: 2009-03-02 23:12:31 +0100
From: Backstage <Backstage@gmx.de>

Yes, i replace the actual offset with the user selection (dismiss,snooze).

I think that the replacement of the offset is better than not having a alarm reminder ;-)

By the way:
I also tested the actual Lightning 1.0pre Version with Thunderbird 3.0b2 where i found following bugs (with WCAP-Calendar):

  1. When i try to insert an event with an alarm time -> The alarm time won't be stored !
  2. Following steps will show "MODIFICATION_FAILED" message:
    a) Insert a new event
    b) Open the created event
    c) "Save/Close" the event without changing anything
    d) --> MODIFICATION_FAILED

@kewisch
Copy link
Owner Author

kewisch commented Mar 2, 2009

Comment 3997425

Date: 2009-03-02 23:52:59 +0100
From: Backstage <Backstage@gmx.de>

Comment on attachment 364975
calAlarmService.js file with fixed alarm reminder

/* ***** BEGIN LICENSE BLOCK *****

  • Version: MPL 1.1/GPL 2.0/LGPL 2.1
  • The contents of this file are subject to the Mozilla Public License Version
  • 1.1 (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.mozilla.org/MPL/
  • Software distributed under the License is distributed on an "AS IS" basis,
  • WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  • for the specific language governing rights and limitations under the
  • License.
  • The Original Code is Oracle Corporation code.
  • The Initial Developer of the Original Code is Oracle Corporation
  • Portions created by the Initial Developer are Copyright (C) 2005
  • the Initial Developer. All Rights Reserved.
  • Contributor(s):
  • Stuart Parmenter stuart.parmenter@oracle.com
  • Joey Minta jminta@gmail.com
  • Daniel Boelzle daniel.boelzle@sun.com
  • Philipp Kewisch mozilla@kewis.ch
  • Martin Schroeder mschroeder@mozilla.x-home.org
  • Alternatively, the contents of this file may be used under the terms of
  • either the GNU General Public License Version 2 or later (the "GPL"), or
  • the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  • in which case the provisions of the GPL or the LGPL are applicable instead
  • of those above. If you wish to allow use of your version of this file only
  • under the terms of either the GPL or the LGPL, and not to allow others to
  • use your version of this file under the terms of the MPL, indicate your
  • decision by deleting the provisions above and replace them with the notice
  • and other provisions required by the GPL or the LGPL. If you do not delete
  • the provisions above, a recipient may use your version of this file under
  • the terms of any one of the MPL, the GPL or the LGPL.
  • ***** END LICENSE BLOCK ***** */

const kHoursBetweenUpdates = 6;

function nowUTC() {
return jsDateToDateTime(new Date()).getInTimezone(UTC());
}

function newTimerWithCallback(callback, delay, repeating)
{
var timer = Components.classes["@mozilla.org/timer;1"].createInstance(Components.interfaces.nsITimer);

timer.initWithCallback(callback,
delay,
(repeating) ? timer.TYPE_REPEATING_PRECISE : timer.TYPE_ONE_SHOT);
return timer;
}

function calAlarmService() {
this.wrappedJSObject = this;

this.mLoadedCalendars = {};
this.mTimerLookup = {};
this.mObservers = new calListenerBag(Components.interfaces.calIAlarmServiceObserver);

this.calendarObserver = {
alarmService: this,

   // calIObserver:
   onStartBatch: function() { },
   onEndBatch: function() { },
   onLoad: function co_onLoad(calendar) {
       // ignore any onLoad events until initial getItems() call of startup has finished:
       if (calendar && this.alarmService.mLoadedCalendars[calendar.id]) {
           // a refreshed calendar signals that it has been reloaded
           // (and cannot notify detailed changes), thus reget all alarms of it:
           this.alarmService.initAlarms([calendar]);
       }
   },
   onAddItem: function(aItem) {
       var occs = [];
       if (aItem.recurrenceInfo) {
           var start = this.alarmService.mRangeEnd.clone();
           // We search 1 month in each direction for alarms.  Therefore,
           // we need to go back 2 months from the end to get this right.
           start.month -= 2;
           occs = aItem.recurrenceInfo.getOccurrences(start, this.alarmService.mRangeEnd, 0, {});
       } else {
           occs = [aItem];
       }

       for each (var occ in occs) {
           this.alarmService.addAlarm(occ);
       }
   },
   onModifyItem: function(aNewItem, aOldItem) {
       if (!aNewItem.recurrenceId) {
           // deleting an occurrence currently calls modifyItem(newParent, *oldOccurrence*)
           aOldItem = aOldItem.parentItem;
       }

       this.onDeleteItem(aOldItem);
       this.onAddItem(aNewItem);
   },
   onDeleteItem: function(aDeletedItem) {
       this.alarmService.removeAlarm(aDeletedItem);
   },
   onError: function(aCalendar, aErrNo, aMessage) {},
   onPropertyChanged: function(aCalendar, aName, aValue, aOldValue) {
       switch (aName) {
           case "suppressAlarms":
           case "disabled":
               this.alarmService.initAlarms([aCalendar]);
               break;
       }
   },
   onPropertyDeleting: function(aCalendar, aName) {
       this.onPropertyChanged(aCalendar, aName);
   }

};

this.calendarManagerObserver = {
alarmService: this,

   onCalendarRegistered: function(aCalendar) {
       this.alarmService.observeCalendar(aCalendar);
       // initial refresh of alarms for new calendar:
       this.alarmService.initAlarms([aCalendar]);
   },
   onCalendarUnregistering: function(aCalendar) {
       // XXX todo: we need to think about calendar unregistration;
       // there may still be dangling items (-> alarm dialog),
       // dismissing those alarms may write data...
       this.alarmService.unobserveCalendar(aCalendar);
   },
   onCalendarDeleting: function(aCalendar) {}

};
}

var calAlarmServiceClassInfo = {
getInterfaces: function (count) {
var ifaces = [
Components.interfaces.nsISupports,
Components.interfaces.calIAlarmService,
Components.interfaces.nsIObserver,
Components.interfaces.nsIClassInfo
];
count.value = ifaces.length;
return ifaces;
},

getHelperForLanguage: function (language) {
return null;
},

contractID: "@mozilla.org/calendar/alarm-service;1",
classDescription: "Calendar Alarm Service",
classID: Components.ID("{7a9200dd-6a64-4fff-a798-c5802186e2cc}"),
implementationLanguage: Components.interfaces.nsIProgrammingLanguage.JAVASCRIPT,
flags: Components.interfaces.nsIClassInfo.SINGLETON
};

calAlarmService.prototype = {
mRangeEnd: null,
mUpdateTimer: null,
mStarted: false,
mTimerLookup: null,
mObservers: null,

QueryInterface: function cas_QueryInterface(aIID) {
if (aIID.equals(Components.interfaces.nsIClassInfo))
return calAlarmServiceClassInfo;

   if (!aIID.equals(Components.interfaces.nsISupports) &&
       !aIID.equals(Components.interfaces.calIAlarmService) &&
       !aIID.equals(Components.interfaces.nsIObserver))
   {
       throw Components.results.NS_ERROR_NO_INTERFACE;
   }

   return this;

},

/* nsIObserver */
// This will also be called on app-startup, but nothing is done yet, to
// prevent unwanted dialogs etc. See bug #325476 and 413296
observe: function cas_observe(subject, topic, data) {
if (topic == "profile-after-change" || topic == "wake_notification") {
this.shutdown();
this.startup();
}
if (topic == "xpcom-shutdown") {
this.shutdown();
}
},

/* calIAlarmService APIs */
mTimezone: null,
get timezone() {
return this.mTimezone || calendarDefaultTimezone();
},

set timezone(aTimezone) {
return (this.mTimezone = aTimezone);
},

snoozeAlarm: function cas_snoozeAlarm(event, duration) {
/* modify the event for a new alarm time */
// Make sure we're working with the parent, otherwise we'll accidentally
// create an exception

   var newEvent = event.parentItem.clone();
   var alarmTime = nowUTC();
  
   // Set the last acknowledged time to now.
   newEvent.alarmLastAck = alarmTime;

   alarmTime = alarmTime.clone();
   alarmTime.addDuration(duration);

   // check if it is a wcap calendar
   if(event.calendar.type != "wcap")
   {
     if (event.parentItem != event) {
         // This is the *really* hard case where we've snoozed a single
         // instance of a recurring event.  We need to not only know that
         // there was a snooze, but also which occurrence was snoozed.  Part
         // of me just wants to create a local db of snoozes here...
         newEvent.setProperty("X-MOZ-SNOOZE-TIME-" + event.recurrenceId.nativeTime,
                              alarmTime.icalString);
     } else {
         newEvent.setProperty("X-MOZ-SNOOZE-TIME", alarmTime.icalString);
     }          
   }
   else
   {
 alarmWithCorrectTimezone = alarmTime.getInTimezone(newEvent.startDate.timezone);
  
 //check if alarm is after event
 if(alarmWithCorrectTimezone.icalString > newEvent.startDate.icalString)
 {
   duration=null;
 }
 else
 {
   // calculate new duration value		  
   duration = alarmWithCorrectTimezone.subtractDate(newEvent.startDate);
 }		
 newEvent.alarmOffset = duration;		
   }
   // calling modifyItem will cause us to get the right callback
   // and update the alarm properly

newEvent.calendar.modifyItem(newEvent, event.parentItem, null);
},

dismissAlarm: function cas_dismissAlarm(item) {
var now = nowUTC();
// We want the parent item, otherwise we're going to accidentally create an
// exception. We've relnoted (for 0.1) the slightly odd behavior this can
// cause if you move an event after dismissing an alarm
var oldParent = item.parentItem;
var newParent = oldParent.clone();
newParent.alarmLastAck = now;
// Make sure to clear out any snoozes that were here.

   // check if it is a wcap calendar

if(newParent.calendar.type=="wcap")
{
newParent.alarmOffset = null;
}
else
{
if (item.recurrenceId) {
newParent.deleteProperty("X-MOZ-SNOOZE-TIME-" + item.recurrenceId.nativeTime);
} else {
newParent.deleteProperty("X-MOZ-SNOOZE-TIME");
}
}

  newParent.calendar.modifyItem(newParent, oldParent, null);

},

addObserver: function cas_addObserver(aObserver) {
this.mObservers.add(aObserver);
},

removeObserver: function cas_removeObserver(aObserver) {
this.mObservers.remove(aObserver);
},

notifyObservers: function cas_notifyObservers(functionName, args) {
this.mObservers.notify(functionName, args);
},

startup: function cas_startup() {
if (this.mStarted)
return;

   LOG("[calAlarmService] starting...");

   var observerSvc = Components.classes["@mozilla.org/observer-service;1"]
                     .getService
                     (Components.interfaces.nsIObserverService);

   observerSvc.addObserver(this, "profile-after-change", false);
   observerSvc.addObserver(this, "xpcom-shutdown", false);
   observerSvc.addObserver(this, "wake_notification", false);

   /* Tell people that we're alive so they can start monitoring alarms.
    */
   this.notifier = Components.classes["@mozilla.org/embedcomp/appstartup-notifier;1"]
                             .getService(Components.interfaces.nsIObserver);
   var notifier = this.notifier;
   notifier.observe(null, "alarm-service-startup", null);

   getCalendarManager().addObserver(this.calendarManagerObserver);

   for each(var calendar in getCalendarManager().getCalendars({})) {
       this.observeCalendar(calendar);
   }

   /* set up a timer to update alarms every N hours */
   var timerCallback = {
       alarmService: this,
       notify: function timer_notify() {
           var now = nowUTC();
           var start;
           if (!this.alarmService.mRangeEnd) {
               // This is our first search for alarms.  We're going to look for
               // alarms +/- 1 month from now.  If someone sets an alarm more than
               // a month ahead of an event, or doesn't start Sunbird/Lightning
               // for a month, they'll miss some, but that's a slim chance
               start = now.clone();
               start.month -= 1;
           } else {
               // This is a subsequent search, so we got all the past alarms before
               start = this.alarmService.mRangeEnd.clone();
           }
           var until = now.clone();
           until.month += 1;
           
           // We don't set timers for every future alarm, only those within 6 hours
           var end = now.clone();
           end.hour += kHoursBetweenUpdates;
           this.alarmService.mRangeEnd = end.getInTimezone(UTC());

           this.alarmService.findAlarms(getCalendarManager().getCalendars({}),
                                        start, until);
       }
   };
   timerCallback.notify();

   this.mUpdateTimer = newTimerWithCallback(timerCallback, kHoursBetweenUpdates * 3600000, true);

   this.mStarted = true;

},

shutdown: function cas_shutdown() {
/* tell people that we're no longer running */
var notifier = this.notifier;
notifier.observe(null, "alarm-service-shutdown", null);

   if (this.mUpdateTimer) {
       this.mUpdateTimer.cancel();
       this.mUpdateTimer = null;
   }
   
   getCalendarManager().removeObserver(this.calendarManagerObserver);

   for each (var cal in this.mTimerLookup) {
       for each (var itemTimers in cal) {
           for each (var timer in itemTimers) {
               if (timer instanceof Components.interfaces.nsITimer) {
                   timer.cancel();
               }
           }
       }
   }
   this.mTimerLookup = {};

   for each(var calendar in getCalendarManager().getCalendars({})) {
       this.unobserveCalendar(calendar);
   }

   this.notifier = null;
   this.mRangeEnd = null;

   var observerSvc = Components.classes["@mozilla.org/observer-service;1"]
                     .getService
                     (Components.interfaces.nsIObserverService);

   observerSvc.removeObserver(this, "profile-after-change");
   observerSvc.removeObserver(this, "xpcom-shutdown");
   observerSvc.removeObserver(this, "wake_notification");

   this.mStarted = false;

},

observeCalendar: function cas_observeCalendar(calendar) {
calendar.addObserver(this.calendarObserver);
},

unobserveCalendar: function cas_unobserveCalendar(calendar) {
calendar.removeObserver(this.calendarObserver);
this.disposeCalendarTimers([calendar]);
this.notifyObservers("onRemoveAlarmsByCalendar", [calendar]);
},

getAlarmDate: function cas_getAlarmTime(aItem) {
var alarmDate = null;
if (aItem.alarmRelated == Components.interfaces.calIItemBase.ALARM_RELATED_START) {
alarmDate = aItem.startDate || aItem.entryDate || aItem.dueDate;
} else {
alarmDate = aItem.endDate || aItem.dueDate || aItem.entryDate;
}

   if (!aItem.alarmOffset || !alarmDate) {
       // If there is no alarm offset, or no date the alarm offset could be
       // relative to, then there is no valid alarm.
       return null;
   }

   alarmDate = alarmDate.clone();

   // Handle all day events.  This is kinda weird, because they don't have
   // a well defined startTime.  We just consider the start/end to be
   // midnight in the user's timezone.
   if (alarmDate.isDate) {
       alarmDate = alarmDate.getInTimezone(this.timezone);
       alarmDate.isDate = false;
   }

   var offset = aItem.alarmOffset;

   alarmDate.addDuration(offset);
   alarmDate = alarmDate.getInTimezone(UTC());

   return alarmDate;

},

addAlarm: function cas_addAlarm(aItem) {
// Get the alarm time
var alarmTime = this.getAlarmDate(aItem);
if (!alarmTime || (isToDo(aItem) && aItem.isCompleted)) {
// If there is no alarm time, don't add the alarm. Also, if the item
// is a task and it is completed, don't add the alarm.
return;
}

   // Check for snooze
   var snoozeTime;
   if (aItem.parentItem != aItem) {
       snoozeTime = aItem.parentItem.getProperty("X-MOZ-SNOOZE-TIME-"+aItem.recurrenceId.nativeTime)
   } else {
       snoozeTime = aItem.getProperty("X-MOZ-SNOOZE-TIME");
   }

   if (snoozeTime && !(snoozeTime instanceof Components.interfaces.calIDateTime)) {
       var time = createDateTime();
       time.icalString = snoozeTime;
       snoozeTime = time;
   }
   LOG("[calAlarmService] considering alarm for item: " + aItem.title +
       " alarm time: " + alarmTime + " snooze time: " + snoozeTime);

   // If the alarm was snoozed, the snooze time is more important.
   alarmTime = snoozeTime || alarmTime;

   var now = jsDateToDateTime(new Date());
   if (alarmTime.timezone.isFloating) {
       now = now.getInTimezone(calendarDefaultTimezone());
       now.timezone = floating();
   } else {
       now = now.getInTimezone(UTC());
   }
   LOG("[calAlarmService] now is " + now);
   var callbackObj = {
       alarmService: this,
       item: aItem,
       notify: function(timer) {
           this.alarmService.alarmFired(this.item);
           this.alarmService.removeTimers(this.item);
       }
   };

   if (alarmTime.compare(now) >= 0) {
       LOG("[calAlarmService] alarm is in the future.");
       // We assume that future alarms haven't been acknowledged

       // delay is in msec, so don't forget to multiply
       var timeout = alarmTime.subtractDate(now).inSeconds * 1000;

       var timeUntilRefresh = this.mRangeEnd.subtractDate(now).inSeconds * 1000;
       if (timeUntilRefresh < timeout) {
           LOG("[calAlarmService] alarm is too late.");
           // we'll get this alarm later.  No sense in keeping an extra timeout
           return;
       }

       this.addTimer(aItem, newTimerWithCallback(callbackObj, timeout, false));
       LOG("[calAlarmService] adding alarm timeout (" + timeout + ") for " + aItem);
   } else {
       var lastAck = aItem.alarmLastAck || aItem.parentItem.alarmLastAck;
       LOG("[calAlarmService] last ack was: " + lastAck);
       // This alarm is in the past.  See if it has been previously ack'd
       if (lastAck && lastAck.compare(alarmTime) >= 0) {
           LOG("[calAlarmService] " + aItem.title + " - alarm previously ackd.");
           return;
       } else { // Fire!
           LOG("[calAlarmService] alarm is in the past and unack'd, firing now!");
           this.alarmFired(aItem);
       }
   }

},

removeAlarm: function cas_removeAlarm(aItem) {
// make sure already fired alarms are purged out of the alarm window:
this.notifyObservers("onRemoveAlarmsByItem", [aItem]);
for each (var timer in this.removeTimers(aItem)) {
if (timer instanceof Components.interfaces.nsITimer) {
timer.cancel();
}
}
},

addTimer: function cas_addTimer(aItem, aTimer) {
var cal = this.mTimerLookup[aItem.calendar.id];
if (!cal) {
cal = {};
this.mTimerLookup[aItem.calendar.id] = cal;
}
var itemTimers = cal[aItem.id];
if (!itemTimers) {
itemTimers = { mCount: 0 };
cal[aItem.id] = itemTimers;
}
var rid = aItem.recurrenceId;
itemTimers[rid ? rid.getInTimezone(UTC()).icalString : "mTimer"] = aTimer;
++itemTimers.mCount;
},

removeTimers: function cas_removeTimers(aItem) {
var cal = this.mTimerLookup[aItem.calendar.id];
if (cal) {
var itemTimers = cal[aItem.id];
if (itemTimers) {
var rid = aItem.recurrenceId;
if (rid) {
rid = rid.getInTimezone(UTC()).icalString;
var timer = itemTimers[rid];
if (timer) {
delete itemTimers[rid];
--itemTimers.mCount;
if (itemTimers.mCount == 0) {
delete cal[aItem.id];
}
return { mTimer: timer };
}
} else {
delete cal[aItem.id];
return itemTimers;
}
}
}
return {};
},

disposeCalendarTimers: function cas_removeCalendarTimers(aCalendars) {
for each (var cal in aCalendars) {
var calTimers = this.mTimerLookup[cal.id];
if (calTimers) {
for each (var itemTimers in calTimers) {
for each (var timer in itemTimers) {
if (timer instanceof Components.interfaces.nsITimer) {
timer.cancel();
}
}
}
delete this.mTimerLookup[cal.id];
}
}
},

findAlarms: function cas_findAlarms(calendars, start, until) {
var getListener = {
alarmService: this,
onOperationComplete: function(aCalendar, aStatus, aOperationType, aId, aDetail) {
// calendar has been loaded, so until now, onLoad events can be ignored:
this.alarmService.mLoadedCalendars[aCalendar.id] = true;
},
onGetResult: function(aCalendar, aStatus, aItemType, aDetail, aCount, aItems) {
for (var i = 0; i < aCount; ++i) {
var item = aItems[i];
// assure we don't fire alarms twice, handle removed alarms as far as we can:
// e.g. we cannot purge removed items from ics files. XXX todo.
this.alarmService.removeAlarm(item);
this.alarmService.addAlarm(item);
}
}
};

   const calICalendar = Components.interfaces.calICalendar;
   var filter = calICalendar.ITEM_FILTER_COMPLETED_ALL |
                calICalendar.ITEM_FILTER_CLASS_OCCURRENCES |
                calICalendar.ITEM_FILTER_TYPE_ALL;

   for each(var calendar in calendars) {
       // assuming that suppressAlarms does not change anymore until refresh:
  	if (!calendar.getProperty("suppressAlarms") &&
           (calendar.getProperty("capabilities.alarms.popup.supported") !== false) &&
           !calendar.getProperty("disabled")) {
           calendar.getItems(filter, 0, start, until, getListener);
       }
   }

},

initAlarms: function cas_initAlarms(calendars) {
// Purge out all alarm timers belonging to the refreshed/loaded calendar:
this.disposeCalendarTimers(calendars);

   // Purge out all alarms from dialog belonging to the refreshed/loaded calendar:
   this.notifyObservers("onRemoveAlarmsByCalendar", calendars);

   // Total refresh similar to startup.  We're going to look for
   // alarms +/- 1 month from now.  If someone sets an alarm more than
   // a month ahead of an event, or doesn't start Sunbird/Lightning
   // for a month, they'll miss some, but that's a slim chance
   var start = nowUTC();
   var until = start.clone();
   start.month -= 1;
   until.month += 1;
   this.findAlarms(calendars, start, until);

},

alarmFired: function cas_alarmFired(event) {
if(event.calendar.type=="wcap")
bIsWCAP = true;
else
bIsWCAP = false;

     if (!bIsWCAP && (event.calendar.getProperty("suppressAlarms") ||
       event.calendar.getProperty("capabilities.alarms.popup.supported") === false)) {
       return;
   }
   this.notifyObservers("onAlarm", [event]);

}
};

@kewisch
Copy link
Owner Author

kewisch commented Mar 2, 2009

Comment 3997440

Date: 2009-03-02 23:59:22 +0100
From: Backstage <Backstage@gmx.de>

Created attachment 365040
calAlarmService.js file with fixed alarm reminder for WCAP calendar only

Comment #15 should be remove...sorry...

Changed the snoozeAlarm behaviour. My changes now only affect WCAP calendar.

Attached file: calAlarmService.js (text/plain, 25043 bytes)
Description: calAlarmService.js file with fixed alarm reminder for WCAP calendar only

@kewisch
Copy link
Owner Author

kewisch commented Mar 3, 2009

Comment 3998102

Date: 2009-03-03 09:04:20 +0100
From: @kewisch

Please only post patches instead of whole files, its really hard to understand this way. Also, make sure you are using the latest version of the file.

See https://developer.mozilla.org/En/Creating_a_patch and https://developer.mozilla.org/en/Mercurial_FAQ#How_can_I_diff_and_patch_files.3F

@kewisch
Copy link
Owner Author

kewisch commented Mar 3, 2009

Comment 3998112

Date: 2009-03-03 09:15:51 +0100
From: Backstage <Backstage@gmx.de>

Sorry!

I only modified the "snoozeAlarm" and "dismissAlarm" methods.

@kewisch
Copy link
Owner Author

kewisch commented Mar 4, 2009

Comment 4000330

Date: 2009-03-04 18:20:29 +0100
From: @dbo

(In reply to comment #14)

Yes, i replace the actual offset with the user selection (dismiss,snooze).

I think that the replacement of the offset is better than not having a alarm
reminder ;-)
Then, what instance restores the original alarm offset? I don't think this approach is sensible. I think we should either

  • go with a server fix (IIRC it's already been fixed, but don't know when it'll be published) and implement the X-prop based solution.
  • may abuse a different alarm type that's yet unsupported, e.g. |alarmFlashing| to store the snooze stamps.

By the way:
I also tested the actual Lightning 1.0pre Version with Thunderbird 3.0b2 where
i found following bugs (with WCAP-Calendar):

  1. When i try to insert an event with an alarm time -> The alarm time won't be
    stored !
  2. Following steps will show "MODIFICATION_FAILED" message:
    a) Insert a new event
    b) Open the created event
    c) "Save/Close" the event without changing anything
    d) --> MODIFICATION_FAILED
    Please, file a new bug for this.

@kewisch
Copy link
Owner Author

kewisch commented Mar 11, 2009

Comment 4010468

Date: 2009-03-11 10:03:13 +0100
From: Vidanez <jvidanez@solucions.ad>

*** Bug #482544 has been marked as a duplicate of this bug. ***

@kewisch
Copy link
Owner Author

kewisch commented Mar 16, 2009

Comment 4017878

Date: 2009-03-16 11:43:14 +0100
From: Vidanez <jvidanez@solucions.ad>

I think maybe this bug is in relation with this other Bug #474426, am I right?
Please for emails reminder see the last note I posted in that bug.
https://bugzilla.mozilla.org/show_bug.cgi?id=396865

@kewisch
Copy link
Owner Author

kewisch commented May 28, 2009

Comment 4119826

Date: 2009-05-28 21:49:41 +0200
From: @dbo

Adding relnote keyword unless we gonna fix this for 1.0...

@kewisch
Copy link
Owner Author

kewisch commented Apr 12, 2010

Comment 4633754

Date: 2010-04-12 15:15:50 +0200
From: Simon Paquet [:sipaq] <bugzilla@babylonsounds.com>

*** Bug #558755 has been marked as a duplicate of this bug. ***

@kewisch
Copy link
Owner Author

kewisch commented Apr 12, 2010

Comment 4633758

Date: 2010-04-12 15:17:43 +0200
From: Maciek <kohut@prosystem.pl>

I've downloaded the calAlarmService.js file (which was attached to that bug) and replaced all this files in my system, but it doesn't resolve this issue. Maybe i did it wrong (means I should apply fixed calAlarmService.js in the different way – not simply replace the files?)

@kewisch
Copy link
Owner Author

kewisch commented Apr 18, 2013

Comment 7329244

Date: 2013-04-18 11:07:10 +0200
From: keesdejong@gmail.com

This bug is still present with Google Calendar notifications, they don't pop-up. Using the Lightning plugin on Ubuntu 12.04.

@kewisch
Copy link
Owner Author

kewisch commented May 30, 2013

Comment 7478615

Date: 2013-05-30 12:38:21 +0200
From: @stoerr

It would also be a big step forward if you could just provide an option to display a popup at the email alarm time, as a workaround. Thus, it'd be usable for now even if I get the additional email notification from the server which I can easily filter to /dev/null.

For me, without popup reminders the WCAP functionality is quite useless - I reliably notice the email quite a long time after the meeting has startet. 8-}

@kewisch kewisch added the enhancement New feature or request label Sep 29, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant