1 /*
  2  * ***** BEGIN LICENSE BLOCK *****
  3  * Zimbra Collaboration Suite Web Client
  4  * Copyright (C) 2011, 2013, 2014, 2016 Synacor, Inc.
  5  *
  6  * The contents of this file are subject to the Common Public Attribution License Version 1.0 (the "License");
  7  * you may not use this file except in compliance with the License.
  8  * You may obtain a copy of the License at: https://www.zimbra.com/license
  9  * The License is based on the Mozilla Public License Version 1.1 but Sections 14 and 15
 10  * have been added to cover use of software over a computer network and provide for limited attribution
 11  * for the Original Developer. In addition, Exhibit A has been modified to be consistent with Exhibit B.
 12  *
 13  * Software distributed under the License is distributed on an "AS IS" basis,
 14  * WITHOUT WARRANTY OF ANY KIND, either express or implied.
 15  * See the License for the specific language governing rights and limitations under the License.
 16  * The Original Code is Zimbra Open Source Web Client.
 17  * The Initial Developer of the Original Code is Zimbra, Inc.  All rights to the Original Code were
 18  * transferred by Zimbra, Inc. to Synacor, Inc. on September 14, 2015.
 19  *
 20  * All portions of the code are Copyright (C) 2011, 2013, 2014, 2016 Synacor, Inc. All Rights Reserved.
 21  * ***** END LICENSE BLOCK *****
 22  */
 23 
 24 /**
 25  * Helper class for applying snooze 'before' times to a set of appointments that
 26  * were handled en-masse in the reminder dialog.
 27  *
 28  * For each appointment
 29  *  - If the appointment has already started (whether in-progress or completed) then the
 30  *    before value is not applied, and we store this appt for later processing.
 31  *  - For appointments that have not started yet:
 32  *     - If the appointment startTime + snoozeTime is in the future (> now) then
 33  *       set the appt reminder untilTime.
 34  *     - If the startTime + snoozeTime is in the past (< now), loop over the
 35  *       standard set of 'before' snooze times and find the max before time that we can
 36  *       apply and still have the reminder occur in the future.
 37  *    Once a time for the appointment's reminder is calculated, save the minimum one (i.e. the
 38  *    reminder for the earlier occuring appt) as earliestUntilTime.
 39  *
 40  * Finally, loop over each of the appointments whose start time is past.
 41  *  - Set their snooze time to the soonestUntilTime.  When the soonest appt reminder goes off,
 42  *    any past appointments will appear too.  The user should dismiss them, but till then they
 43  *    are dragged along
 44  *
 45  */
 46 ZmSnoozeBeforeProcessor = function(apptType) {
 47     this._apptType = apptType;
 48 }
 49 ZmSnoozeBeforeProcessor.prototype.constructor = ZmSnoozeBeforeProcessor;
 50 
 51 
 52 ZmSnoozeBeforeProcessor.prototype.execute =
 53 function(apptList, chosenSnoozeMilliseconds, appts) {
 54     var added = false;
 55     var untilTime;
 56     var earliestUntilTime = 0;
 57     var pastAppts = [];
 58     var actionNode;
 59     var now = (new Date()).getTime();
 60     for (var i = 0; i < apptList.size(); i++) {
 61         var appt = apptList.get(i);
 62         var apptStartTime = appt.getAlarmInstStart();
 63         var snoozeMilliseconds = chosenSnoozeMilliseconds;
 64         if (apptStartTime <= now) {
 65             // Past or in progress appt.  Once we determine the earliest untilTime,
 66             // we will apply it to these appts, to 'drag them along'
 67             pastAppts.push(appt);
 68         } else {
 69             // Only apply snooze reminder for appts that have not already started
 70             snoozeMilliseconds = -snoozeMilliseconds
 71             untilTime = apptStartTime + snoozeMilliseconds;
 72             // Test that the chosen 'before' time is valid for this appt.  The user may
 73             // have entered a value that would cause a reminder to be scheduled for the past.
 74             // So check the user specified snoozeTime (untilTime = apptStart + snoozeTime); if it
 75             // is in the past, loop over the standard 'before' snooze intervals and choose the
 76             // first that results in a reminder scheduled for the future.
 77             for (var iSnooze = 0; iSnooze < ZmReminderDialog.SNOOZE_MSEC.length; iSnooze++) {
 78                 if ((untilTime >= now) || (snoozeMilliseconds >= 0)) break;
 79                 snoozeMilliseconds = ZmReminderDialog.SNOOZE_MSEC[iSnooze];
 80                 untilTime = apptStartTime + snoozeMilliseconds;
 81             }
 82 
 83             if (snoozeMilliseconds < 0) {
 84                 // Found a valid untilTime
 85                 var apptInfo = { id: appt.id, until: untilTime};
 86                 appts.push(apptInfo)
 87 
 88 
 89                 added = true;
 90                 if ((earliestUntilTime ==0) || (earliestUntilTime > untilTime)) {
 91                     // Keep track of the earliest reminder that will occur
 92                     earliestUntilTime = untilTime;
 93                 }
 94             }
 95         }
 96     }
 97 
 98     if (added) {
 99         // At least one future appt was added.  Take the one with the earliest reminder
100         // and apply it to past appointments
101         for (var i = 0; i < pastAppts.length; i++) {
102            var apptInfo = { id: pastAppts[i].id, until: earliestUntilTime};
103             appts.push(apptInfo)
104         }
105     }
106     return added;
107 }
108 
109