1 /* 2 * ***** BEGIN LICENSE BLOCK ***** 3 * Zimbra Collaboration Suite Web Client 4 * Copyright (C) 2011, 2012, 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, 2012, 2014, 2016 Synacor, Inc. All Rights Reserved. 21 * ***** END LICENSE BLOCK ***** 22 */ 23 /** 24 * Date group divides messages into the following sections: 25 * Today 26 * Yesterday 27 * Day of week -- not today or yesterday, but still within this week 28 * Last Week 29 * Two Weeks Ago 30 * Three Weeks Ago 31 * Earlier this Month 32 * Last Month 33 * Older 34 * 35 */ 36 ZmMailListDateGroup = function(){ 37 this.id = ZmId.GROUPBY_DATE; 38 this.field = ZmItem.F_DATE; 39 this._weekStartDay = appCtxt.get(ZmSetting.CAL_FIRST_DAY_OF_WEEK) || 0; 40 var dayOfWeek = this._getToday().getDay(); 41 this._keys = this._sortKeys(dayOfWeek, false); 42 ZmMailListGroup.call(this); 43 }; 44 45 ZmMailListDateGroup.prototype = new ZmMailListGroup; 46 ZmMailListDateGroup.prototype.constructor = ZmMailListDateGroup; 47 48 ZmMailListDateGroup.MONDAY = "MONDAY"; 49 ZmMailListDateGroup.TUESDAY = "TUESDAY"; 50 ZmMailListDateGroup.WEDNESDAY = "WEDNESDAY"; 51 ZmMailListDateGroup.THURSDAY = "THURSDAY"; 52 ZmMailListDateGroup.FRIDAY = "FRIDAY"; 53 ZmMailListDateGroup.SATURDAY = "SATURDAY"; 54 ZmMailListDateGroup.SUNDAY = "SUNDAY"; 55 ZmMailListDateGroup.TODAY = "TODAY"; 56 ZmMailListDateGroup.YESTERDAY = "YESTERDAY"; 57 ZmMailListDateGroup.LAST_WEEK = "LAST_WEEK"; 58 ZmMailListDateGroup.TWO_WEEKS_AGO = "TWO_WEEKS_AGO"; 59 ZmMailListDateGroup.THREE_WEEKS_AGO = "THREE_WEEKS_AGO"; 60 ZmMailListDateGroup.EARLIER_THIS_MONTH = "EARLIER_THIS_MONTH"; 61 ZmMailListDateGroup.LAST_MONTH = "LAST_MONTH"; 62 ZmMailListDateGroup.OLDER = "OLDER"; 63 64 ZmMailListDateGroup.GROUP = [ZmMailListDateGroup.TODAY, ZmMailListDateGroup.YESTERDAY, ZmMailListDateGroup.SUNDAY, ZmMailListDateGroup.MONDAY, 65 ZmMailListDateGroup.TUESDAY, ZmMailListDateGroup.WEDNESDAY, ZmMailListDateGroup.THURSDAY, ZmMailListDateGroup.FRIDAY, 66 ZmMailListDateGroup.SATURDAY, ZmMailListDateGroup.LAST_WEEK, ZmMailListDateGroup.TWO_WEEKS_AGO, ZmMailListDateGroup.THREE_WEEKS_AGO, 67 ZmMailListDateGroup.EARLIER_THIS_MONTH, ZmMailListDateGroup.LAST_MONTH, ZmMailListDateGroup.OLDER]; 68 69 ZmMailListDateGroup.WEEKDAYS = [ZmMailListDateGroup.SUNDAY, ZmMailListDateGroup.MONDAY, ZmMailListDateGroup.TUESDAY, ZmMailListDateGroup.WEDNESDAY, 70 ZmMailListDateGroup.THURSDAY, ZmMailListDateGroup.FRIDAY, ZmMailListDateGroup.SATURDAY]; 71 72 ZmMailListDateGroup.SECTION_TITLE = {}; 73 ZmMailListDateGroup.SECTION_TITLE[ZmMailListDateGroup.TODAY] = ZmMsg.today; 74 ZmMailListDateGroup.SECTION_TITLE[ZmMailListDateGroup.YESTERDAY] = ZmMsg.yesterday; 75 ZmMailListDateGroup.SECTION_TITLE[ZmMailListDateGroup.MONDAY] = I18nMsg.weekdayMonLong; 76 ZmMailListDateGroup.SECTION_TITLE[ZmMailListDateGroup.TUESDAY] = I18nMsg.weekdayTueLong; 77 ZmMailListDateGroup.SECTION_TITLE[ZmMailListDateGroup.WEDNESDAY] = I18nMsg.weekdayWedLong; 78 ZmMailListDateGroup.SECTION_TITLE[ZmMailListDateGroup.THURSDAY] = I18nMsg.weekdayThuLong; 79 ZmMailListDateGroup.SECTION_TITLE[ZmMailListDateGroup.FRIDAY] = I18nMsg.weekdayFriLong; 80 ZmMailListDateGroup.SECTION_TITLE[ZmMailListDateGroup.SATURDAY] = I18nMsg.weekdaySatLong; 81 ZmMailListDateGroup.SECTION_TITLE[ZmMailListDateGroup.SUNDAY] = I18nMsg.weekdaySunLong; 82 ZmMailListDateGroup.SECTION_TITLE[ZmMailListDateGroup.LAST_WEEK] = ZmMsg.lastWeek; 83 ZmMailListDateGroup.SECTION_TITLE[ZmMailListDateGroup.TWO_WEEKS_AGO] = ZmMsg.twoWeeksAgo; 84 ZmMailListDateGroup.SECTION_TITLE[ZmMailListDateGroup.THREE_WEEKS_AGO] = ZmMsg.threeWeeksAgo; 85 ZmMailListDateGroup.SECTION_TITLE[ZmMailListDateGroup.EARLIER_THIS_MONTH] = ZmMsg.earlierThisMonth; 86 ZmMailListDateGroup.SECTION_TITLE[ZmMailListDateGroup.LAST_MONTH] = ZmMsg.lastMonth; 87 ZmMailListDateGroup.SECTION_TITLE[ZmMailListDateGroup.OLDER] = ZmMsg.older; 88 89 ZmMailListDateGroup.TIME = {}; 90 ZmMailListDateGroup.TIME["YESTERDAY"] = AjxDateUtil.MSEC_PER_DAY; 91 ZmMailListDateGroup.TIME["LAST_WEEK"] = AjxDateUtil.MSEC_PER_DAY * 7; 92 ZmMailListDateGroup.TIME["TWO_WEEKS_AGO"] = AjxDateUtil.MSEC_PER_DAY * 14; 93 ZmMailListDateGroup.TIME["THREE_WEEKS_AGO"] = AjxDateUtil.MSEC_PER_DAY * 21; 94 95 96 /** 97 * returns HTML string for all sections. 98 * @param {boolean} sortAsc true/false if sort ascending 99 * @return {String} HTML for all sections including section header 100 * @param sortAsc 101 */ 102 ZmMailListDateGroup.prototype.getAllSections = 103 function(sortAsc) { 104 var htmlArr = []; 105 var dayOfWeek = this._getToday().getDay(); 106 var keys = sortAsc ? this._sortKeys(dayOfWeek, sortAsc) : this._keys; //keys have already been sorted desc 107 for (var i=0; i<keys.length; i++) { 108 if (this._section[keys[i]].length > 0) { 109 htmlArr.push(this.getSectionHeader(ZmMailListDateGroup.SECTION_TITLE[keys[i]])); 110 htmlArr.push(this._section[keys[i]].join("")); 111 } 112 else if (this._showEmptySectionHeader) { 113 htmlArr.push(this.getSectionHeader(ZmMailListDateGroup.SECTION_TITLE[keys[i]])); 114 } 115 } 116 return htmlArr.join(""); 117 }; 118 119 /** 120 * Adds item to section 121 * @param {ZmMailMsg} msg mail message 122 * @param {String} item HTML to add to section 123 * @return {String} section returns section if successfully added, else returns null 124 */ 125 ZmMailListDateGroup.prototype.addMsgToSection = 126 function(msg, item) { 127 for (var i=0; i<this._keys.length; i++) { 128 if (this.isMsgInSection(this._keys[i], msg)) { 129 this._section[this._keys[i]].push(item); 130 return this._keys[i]; 131 } 132 } 133 }; 134 135 /** 136 * Determines if message is in group 137 * @param {String} section ID of section 138 * @param {ZmMailMsg} msg 139 * @return {boolean} true/false 140 */ 141 ZmMailListDateGroup.prototype.isMsgInSection = 142 function(section, msg) { 143 144 switch(section){ 145 case ZmMailListDateGroup.TODAY: 146 return this._isToday(msg); 147 148 case ZmMailListDateGroup.YESTERDAY: 149 return this._isYesterday(msg); 150 151 case ZmMailListDateGroup.MONDAY: 152 return this._isDayOfWeek(msg, AjxDateUtil.MONDAY); 153 154 case ZmMailListDateGroup.TUESDAY: 155 return this._isDayOfWeek(msg, AjxDateUtil.TUESDAY); 156 157 case ZmMailListDateGroup.WEDNESDAY: 158 return this._isDayOfWeek(msg, AjxDateUtil.WEDNESDAY); 159 160 case ZmMailListDateGroup.THURSDAY: 161 return this._isDayOfWeek(msg, AjxDateUtil.THURSDAY); 162 163 case ZmMailListDateGroup.FRIDAY: 164 return this._isDayOfWeek(msg, AjxDateUtil.FRIDAY); 165 166 case ZmMailListDateGroup.SATURDAY: 167 return this._isDayOfWeek(msg, AjxDateUtil.SATURDAY); 168 169 case ZmMailListDateGroup.SUNDAY: 170 return this._isDayOfWeek(msg, AjxDateUtil.SUNDAY); 171 172 case ZmMailListDateGroup.LAST_WEEK: 173 return this._isWeeksAgo(msg, ZmMailListDateGroup.LAST_WEEK, ZmMailListDateGroup.YESTERDAY); 174 175 case ZmMailListDateGroup.TWO_WEEKS_AGO: 176 return this._isWeeksAgo(msg, ZmMailListDateGroup.TWO_WEEKS_AGO, ZmMailListDateGroup.LAST_WEEK); 177 178 case ZmMailListDateGroup.THREE_WEEKS_AGO: 179 return this._isWeeksAgo(msg, ZmMailListDateGroup.THREE_WEEKS_AGO, ZmMailListDateGroup.TWO_WEEKS_AGO); 180 181 case ZmMailListDateGroup.EARLIER_THIS_MONTH: 182 return this._isEarlierThisMonth(msg); 183 184 case ZmMailListDateGroup.LAST_MONTH: 185 return this._isLastMonth(msg); 186 187 case ZmMailListDateGroup.OLDER: 188 return this._isOlder(msg); 189 190 default: 191 return false; 192 } 193 }; 194 195 /** 196 * Returns the sort by (ZmSearch.DATE_ASC or ZmSearch.DATE_DESC) 197 * @param {boolean} sortAsc 198 * @return {String} sortBy 199 */ 200 ZmMailListDateGroup.prototype.getSortBy = 201 function(sortAsc) { 202 if (sortAsc) { 203 return ZmSearch.DATE_ASC; 204 } 205 return ZmSearch.DATE_DESC; 206 }; 207 208 ZmMailListDateGroup.prototype._init = 209 function(){ 210 this._section = {}; 211 this._section[ZmMailListDateGroup.TODAY] = []; 212 this._section[ZmMailListDateGroup.YESTERDAY] = []; 213 this._section[ZmMailListDateGroup.SUNDAY] = []; 214 this._section[ZmMailListDateGroup.MONDAY] = []; 215 this._section[ZmMailListDateGroup.TUESDAY] = []; 216 this._section[ZmMailListDateGroup.WEDNESDAY] = []; 217 this._section[ZmMailListDateGroup.THURSDAY] = []; 218 this._section[ZmMailListDateGroup.FRIDAY] = []; 219 this._section[ZmMailListDateGroup.SATURDAY] = []; 220 this._section[ZmMailListDateGroup.LAST_WEEK] = []; 221 this._section[ZmMailListDateGroup.TWO_WEEKS_AGO] = []; 222 this._section[ZmMailListDateGroup.THREE_WEEKS_AGO] = []; 223 this._section[ZmMailListDateGroup.EARLIER_THIS_MONTH] = []; 224 this._section[ZmMailListDateGroup.LAST_MONTH] = []; 225 this._section[ZmMailListDateGroup.OLDER] = []; 226 }; 227 228 /** 229 * determines if mail message was received today 230 * @param msg {ZmMailMsg} mail msg 231 * @return {boolean} 232 */ 233 ZmMailListDateGroup.prototype._isToday = 234 function(msg){ 235 if(msg){ 236 var today = this._getToday(); 237 var d = this._getDateFromMsg(msg, true); 238 if (d) { 239 return today.getTime() == d.getTime(); 240 } 241 } 242 return false; 243 }; 244 245 /** 246 * determines if msg was received yesterday 247 * @param msg {ZmMailMsg} mail msg 248 * @return {boolean} 249 */ 250 ZmMailListDateGroup.prototype._isYesterday = 251 function(msg) { 252 if (msg) { 253 var today = this._getToday(); 254 var yesterday = new Date(); 255 yesterday.setTime(today.getTime() - AjxDateUtil.MSEC_PER_DAY); 256 var d = this._getDateFromMsg(msg, true); 257 if (d) { 258 return yesterday.getTime() == d.getTime(); 259 } 260 } 261 262 return false; 263 }; 264 265 /** 266 * message is this week, but not today or yesterday 267 * @param msg {ZmMailMsg} mail msg 268 * @param dayOfWeek {integer} the day of the week to check against (e.g. Monday) 269 * @return {boolean} 270 */ 271 ZmMailListDateGroup.prototype._isDayOfWeek = 272 function(msg, dayOfWeek) { 273 if (msg) { 274 var today = this._getToday(); 275 var thisWeek = AjxDateUtil.getWeekNumber(today); 276 var thisYear = today.getYear(); 277 278 var d = this._getDateFromMsg(msg, true); 279 if (d) { 280 return d.getDay() == dayOfWeek && AjxDateUtil.getWeekNumber(d) == thisWeek && 281 !this._isYesterday(msg) && !this._isToday(msg) && thisYear == d.getYear(); 282 } 283 } 284 return false; 285 }; 286 287 /** 288 * Determines if msg is from X number of weeks ago. 289 * @param {ZmMailMsg} msg the mail message to evaluate 290 * @param {String} minGroup Group oldest in date (e.g. three weeks ago) 291 * @param {String} maxGroup Group newest in date (e.g. two weeks ago) 292 */ 293 ZmMailListDateGroup.prototype._isWeeksAgo = 294 function(msg, minGroup, maxGroup) { 295 if (msg) { 296 var today = this._getToday(); 297 var max = today.getTime() - ZmMailListDateGroup.TIME[maxGroup]; 298 var min = today.getTime() - ZmMailListDateGroup.TIME[minGroup]; 299 var d = this._getDateFromMsg(msg, true); 300 if (d) { 301 return d.getTime() >= min && d.getTime() < max; 302 } 303 } 304 305 return false; 306 }; 307 308 /** 309 * message is earlier this month and also more than 3 weeks ago 310 * @param msg {ZmMailMsg} mail msg 311 * @return {boolbean} 312 */ 313 ZmMailListDateGroup.prototype._isEarlierThisMonth = 314 function(msg) { 315 if (msg) { 316 var today = this._getToday(); 317 var threeWeeksAgo = today.getTime() - ZmMailListDateGroup.TIME[ZmMailListDateGroup.THREE_WEEKS_AGO]; 318 var thisMonth = today.getMonth(); 319 var thisYear = today.getYear(); 320 var d = this._getDateFromMsg(msg, true); 321 if (d) { 322 return d.getTime() < threeWeeksAgo && (d.getYear() == thisYear && d.getMonth() == thisMonth); 323 } 324 } 325 return false; 326 }; 327 328 /** 329 * message is last month and also more than 3 weeks ago from today 330 * @param msg {ZmMailMsg} mail message 331 * @return {boolean} 332 */ 333 ZmMailListDateGroup.prototype._isLastMonth = 334 function(msg) { 335 if (msg) { 336 var today = this._getToday(); 337 var threeWeeksAgo = today.getTime() - ZmMailListDateGroup.TIME[ZmMailListDateGroup.THREE_WEEKS_AGO]; 338 var thisMonth = today.getMonth(); 339 var thisYear = today.getYear(); 340 var lastMonth = this._calculateLastMonth(thisMonth); 341 var d = this._getDateFromMsg(msg, true); 342 if (d) { 343 if(d.getMonth() != thisMonth) { 344 if (d.getYear() == thisYear) { 345 return d.getMonth() == lastMonth && d.getTime() < threeWeeksAgo; 346 } 347 else if (d.getYear() == (thisYear -1) && thisMonth == 0 && lastMonth == 11) { 348 //handle the january, december case 349 return d.getTime() < threeWeeksAgo; 350 } 351 } 352 } 353 354 } 355 return false; 356 }; 357 358 /** 359 * message is more than a month old 360 * @param msg {ZmMailMsg} mail msg 361 * @return {boolean} 362 */ 363 ZmMailListDateGroup.prototype._isOlder = 364 function(msg) { 365 if (msg) { 366 var today = this._getToday(); 367 var threeWeeksAgo = today.getTime() - ZmMailListDateGroup.TIME[ZmMailListDateGroup.THREE_WEEKS_AGO]; 368 var d = this._getDateFromMsg(msg, true); 369 if (d) { 370 return d.getTime() < threeWeeksAgo && !this._isEarlierThisMonth(msg) && !this._isLastMonth(msg); 371 } 372 } 373 return false; 374 }; 375 376 ZmMailListDateGroup.prototype._getDateFromMsg = 377 function(msg, resetHours) { 378 if (msg) { 379 var d = msg.sentDate ? new Date(msg.sentDate) : new Date(msg.date); 380 if (d && resetHours) { 381 d.setHours(0, 0, 0, 0); 382 } 383 return d; 384 } 385 return null; 386 }; 387 388 /** 389 * Sorts sections (e.g. Today, Yesterday, Days, Last Week, etc) by ASC or DESC order. dayOfWeek is used to sort the week days in ASC/DESC order 390 * @param dayOfWeek {integer} day value of today 391 * @param sortAsc {boolean} true if sort ascending 392 * @return keys {array} sorted keys 393 */ 394 ZmMailListDateGroup.prototype._sortKeys = 395 function(dayOfWeek, sortAsc) { 396 var keys = []; 397 var sortedDays = this._sortThisWeek(dayOfWeek); 398 sortedDays = sortedDays.slice(2); //account for today & yesterday 399 keys = [ZmMailListDateGroup.TODAY, ZmMailListDateGroup.YESTERDAY]; 400 keys = keys.concat(sortedDays); 401 keys = keys.concat([ZmMailListDateGroup.LAST_WEEK, ZmMailListDateGroup.TWO_WEEKS_AGO, ZmMailListDateGroup.THREE_WEEKS_AGO, 402 ZmMailListDateGroup.EARLIER_THIS_MONTH, ZmMailListDateGroup.LAST_MONTH, ZmMailListDateGroup.OLDER]); 403 if (sortAsc) { 404 keys.reverse(); 405 } 406 return keys; 407 }; 408 409 ZmMailListDateGroup.prototype._calculateLastMonth = 410 function(month) { 411 var lastMonth = month -1; 412 if (lastMonth == -1){ 413 lastMonth = 11; 414 } 415 return lastMonth; 416 }; 417 418 ZmMailListDateGroup.prototype._getToday = 419 function() { 420 var today = new Date(); 421 today.setHours(0,0,0,0); 422 return today; 423 }; 424 425 ZmMailListDateGroup.prototype._getSectionHeaderTitle = 426 function(section) { 427 if (ZmMailListDateGroup.SECTION_TITLE[section]) { 428 return ZmMailListDateGroup.SECTION_TITLE[section]; 429 } 430 431 return ""; 432 }; 433 434 /** 435 * Sort days for this week. If today is Monday & preferences is start week with Sunday, result will by [Monday, Sunday] 436 * @param firstDay {integer} day value of today 437 * @return sorteDays {array} array of sorted days 438 */ 439 ZmMailListDateGroup.prototype._sortThisWeek = 440 function(firstDay) { 441 var sortedDays = []; 442 var count = 0; 443 var foundStart = false; 444 while (count < 7 && !foundStart) { 445 if (firstDay == this._weekStartDay) { 446 foundStart = true; 447 } 448 sortedDays[count] = ZmMailListDateGroup.WEEKDAYS[firstDay]; 449 firstDay--; 450 if (firstDay < 0) { 451 firstDay = 6; 452 } 453 count++; 454 } 455 456 return sortedDays; 457 }; 458