/* Copyright 2010 Palm, Inc. All rights reserved. */ /*jslint laxbreak: true, white: false, devel: true */ /*global Class: false, Mojo: false, $L: false, Template: false, getAppAssistant: false */ var ReminderAssistant = Class.create({ initialize: function(eventId,needThrobbing) { Mojo.Log.info("$$$$$$$$ Reminder-assistant initialize: start: "+eventId); this.DEFAULT_SNOOZE = 5; this.app = getAppAssistant(); this.reminders = this.app.getReminderManager(); this.app.openReminderAlert = this; this.requests = []; this.dismissed = false; this.snoozed = false; this.eventId = eventId; this.doThrob = needThrobbing; this.autoSnoozed = false; Mojo.Log.info("$$$$$$$$ Reminder-assistant initialize:end"); }, activate:function(){ Mojo.Log.info("$$$$$$$$ Reminder-assistant activate:start"); if (this.doThrob) { Mojo.Log.info("$$$$$$$$ Reminder-assistant doThrob:true"); this.controller.stageController.indicateNewContent(true); } Mojo.Log.info("$$$$$$$$ Reminder-assistant activate:end"); }, setup: function() { Mojo.Log.info("$$$$$$$$ Reminder-assistant setup:start"); this.reminders.observeReminders ("alert", this); this.onEventHandler = this.onEvent .bindAsEventListener(this); this.onDismissHandler = this.onDismiss.bindAsEventListener(this); this.onEmailHandler = this.onEmail .bindAsEventListener(this); this.onSnoozeHandler = this.onSnooze .bindAsEventListener(this); this.updateMostRecentReminder(); Mojo.Log.info("$$$$$$$$ Reminder-assistant setup:end"); }, cleanup: function() { Mojo.Log.info("$$$$$$$$ Reminder-assistant cleanup:start:"); this.reminders.stopObservingReminders('alert'); getAppAssistant().openReminderAlert = null; if (this.reminder) { Mojo.Log.info("$$$$$$$$ Reminder Assistant cleanup for:"+this.reminder.id); if (!this.dismissed && this.reminders.getReminder(this.reminder.id)/*this might be an auto close task and hence already removed*/) { Mojo.Log.info("$$$$$$$$ Reminder-assistant cleanup: snoozing reminder " + this.reminder.id); this.snooze(this.DEFAULT_SNOOZE); } if (this.dismissed || this.snoozed) { Mojo.Log.info("$$$$$$$$ Reminder-assistant cleanup : removing autoclosetask"); //only remove the auto close task if it is acted upon this.removeAutoCloseTask(); } } Mojo.Log.info("$$$$$$$$ Reminder-assistant cleanup:end:"); }, remindersUpdated: function() { Mojo.Log.info("$$$$$$$$ Reminder-assistant remindersUpdated: start"); if (this.autoSnoozed) { Mojo.Log.info("$$$$$$$$ Reminder-assistant remindersUpdated: autoSnoozed so returning..."); return; } if (this.reminders.getNumReminders() === 0) { Mojo.Log.info("$$$$$$$$ Reminder-assistant remindersUpdated:closingAlert"); this.closeAlert(); } else { Mojo.Log.info("$$$$$$$$ Reminder-assistant remindersUpdated:updateMostRecentReminder"); this.updateMostRecentReminder(); } Mojo.Log.info("$$$$$$$$ Reminder-assistant remindersUpdated: end"); }, updateMostRecentReminder: function() { Mojo.Log.info("$$$$$$$$ Reminder-assistant updateMostRecentReminder:start"); //this.reminder = this.reminders.getMostRecentReminder(); this.reminder = this.reminders.getReminder(this.eventId); if(!this.reminder){ //the reminder manager does not have any reminders //so just close this scene and return. this.closeAlert(); return; } this.scheduleAtStartTime(); this.scheduleAutoCloseTask(); this.updateDisplay(); Mojo.Log.info("$$$$$$$$ Reminder-assistant updateMostRecentReminder:end"); }, updateDisplay: function() { Mojo.Log.info("$$$$$$$$ Reminder-assistant updateDisplay:start, StageName:"+this.controller.window.name); var data = {}; data.subject = this.reminder.subject; if (!data.subject) { data.subject = ''; } if (this.reminder.time || this.reminder.isAllDay) { var timeStartStr; var ampmStr; if(this.reminder.isAllDay) { data.time = Mojo.Format.formatDate(new Date(this.reminder.time), $L("MMM d, yyyy")); } else if (this.app.getTimeFormat() == "HH12") { data.time = Mojo.Format.formatDate(new Date(this.reminder.time), $L('EEE MMM d, h:mm a')); } else { data.time = Mojo.Format.formatDate(new Date(this.reminder.time), $L('EEE MMM d, H:mm')); } } if (this.reminder.location) { data.location = this.reminder.location; } else { data.location = $L("No location"); } this.removeListeners(); var eventHtml = Mojo.View.render({object: data, template: 'reminder/reminder-event'}); this.updateHTML(this.controller.get('reminder-event'), eventHtml); if (this.reminder.attendees.length > 1/* we now include the organizer in the attendee list*/) { this.controller.get('reminder-email').style.display = ''; this.controller.get('reminder-email').addEventListener(Mojo.Event.tap, this.onEmailHandler); } this.addListeners(); Mojo.Log.info("$$$$$$$$ Reminder-assistant updateDisplay:end"); }, addListeners: function() { this.controller.get('notification-event-title').addEventListener(Mojo.Event.tap, this.onEventHandler); this.controller.get('notification-event-subtitle').addEventListener(Mojo.Event.tap, this.onEventHandler); this.controller.get('notification-event-icon').addEventListener(Mojo.Event.tap, this.onEventHandler); this.controller.get('notification-event-location').addEventListener(Mojo.Event.tap, this.onEventHandler); this.controller.get('reminder-dismiss').addEventListener(Mojo.Event.tap, this.onDismissHandler); this.controller.get('reminder-snooze').addEventListener(Mojo.Event.tap, this.onSnoozeHandler); }, removeListeners: function() { var title = this.controller.get('notification-event-title'); if (title) { title.removeEventListener(Mojo.Event.tap, this.onEventHandler); } var subtitle = this.controller.get('notification-event-subtitle'); if (subtitle) { subtitle.removeEventListener(Mojo.Event.tap, this.onEventHandler); } var location = this.controller.get('notification-event-location'); if (location) { location.removeEventListener(Mojo.Event.tap, this.onEventHandler); } var icon =this.controller.get('notification-event-icon'); if (icon) { icon.removeEventListener(Mojo.Event.tap, this.onEventHandler); } var dismiss = this.controller.get('reminder-dismiss'); if (dismiss) { dismiss.removeEventListener(Mojo.Event.tap, this.onDismissHandler); } var email = this.controller.get('reminder-email'); if (email) { email.removeEventListener(Mojo.Event.tap, this.onEmailHandler); } var snooze = this.controller.get('reminder-snooze'); if (snooze) { snooze.removeEventListener(Mojo.Event.tap, this.onSnoozeHandler); } }, formatTimeText: function(date1, date2) { var minsInDay = 24 * 60; var t1 = $L('in #{min} mins'); var t2 = $L('in #{hour} hrs #{min} mins'); var t3 = $L('#{min} mins ago'); var t4 = $L('#{hour} hrs #{min} mins ago'); var t5 = $L('in #{day} days #{hour} hrs #{min} mins'); var t6 = $L('#{day} days #{hour} hrs #{min} mins ago'); var timeDelta = {}; var template; var days1 = date1.getDayOfYear(); var days2 = date2.getDayOfYear(); var year1 = date1.getFullYear(); var year2 = date2.getFullYear(); for (var y1 = year1; y1 < year2; y1++) { days2 += Date.isLeapYear(y1) ? 366: 365; } for (var y2 = year2; y2 < year1; y2++) { days1 += Date.isLeapYear(y2) ? 366: 365; } var dt = (days1 - days2) * minsInDay + (date1.getHours() - date2.getHours()) * 60 + (date1.getMinutes() - date2.getMinutes()); if (dt < 0) { dt = Math.abs(dt); if (dt >= minsInDay) { template = new Template(t6); timeDelta.day = Math.floor(dt / minsInDay); timeDelta.hour = Math.floor(dt / 60) % 24; timeDelta.min = dt % 60; }else if (dt >= 60) { template = new Template(t4); timeDelta.hour = Math.floor(dt / 60); timeDelta.min = dt % 60; } else { template = new Template(t3); timeDelta.min = dt; } } else { if (dt >= (24 * 60)) { template = new Template(t5); timeDelta.day = Math.floor(dt / minsInDay); timeDelta.hour = Math.floor(dt / 60) % 24; timeDelta.min = dt % 60; } else if (dt >= 60) { template = new Template(t2); timeDelta.hour = Math.floor(dt / 60); timeDelta.min = dt % 60; } else { template = new Template(t1); timeDelta.min = dt; } } return template.evaluate(timeDelta); }, //If there are autosnoozed reminders, and the displayed reminder is snoozed or dismissed, //display the most recent autosnoozed reminder. reissueAutoSnoozedAlerts: function(){ var reminders = this.app.getReminderManager().getAllReminders(); var now = new Date().getTime(); var reminder; //Scan the list, find which autosnoozed alarm's start time is most recent Mojo.Log.info("$$$$$$$$ Reminder-assistant reissueAutoSnoozedAlerts start: reminders in list: "+reminders.size()); var latestReminderIndex = -1; var latestStartTime = 0; for(var i = 0; i < reminders.size(); i++){ reminder = reminders[i]; var closeTime = new Date(reminder.time + reminder.duration); if(now < closeTime && reminder.time > latestStartTime && reminder.userClosed === false){ latestStartTime = reminder.time; latestReminderIndex = i; } } //Reissue the alarm. if (latestReminderIndex != -1) { reminder = reminders[latestReminderIndex]; Mojo.Log.info("$$$$$$$$ Reminder-assistant reissueAutoSnoozedAlerts reissuing: "+reminder.id); var request = new Mojo.Service.Request('palm://com.palm.applicationManager', { method: 'open', parameters: { 'id': 'com.palm.app.calendar', 'params': {'alarmsnooze': reminder.id,'dontAlert':true} } }); } }, onEvent: function(event) { Mojo.Log.info("$$$$$$$$ Reminder-assistant onEvent: start: " + this.reminder.id); this.dismissed = true; this.closeAlert(); this.removeReminder(); this.showEventDetails(); Mojo.Log.info("$$$$$$$$ Reminder-assistant onEvent: end: " + this.reminder.id); }, onDismiss: function(event) { Mojo.Log.info("$$$$$$$$ Reminder-assistant onDismiss: start: " + this.reminder.id); this.dismissed = true; this.closeAlert(); this.removeReminder(); this.autoSnoozed = false; this.reminder.userClosed = true; this.reissueAutoSnoozedAlerts(); Mojo.Log.info("$$$$$$$$ Reminder-assistant onDismiss: end: " + this.reminder.id); }, onEmail: function(event) { Mojo.Log.info("$$$$$$$$ Reminder-assistant onEmail: start " + this.reminder.id); if (this.reminder.attendees.length > 0) { var messageBody = $L("Running late, on my way..."); this.app.getAppManagerService().launchComposeMessage(this.controller ,this.reminder.subject ,this.reminder.attendees ,messageBody ,this.reminder.emailAccountId); this.closeAlert(); } Mojo.Log.info("$$$$$$$$ Reminder-assistant onEmail: end " + this.reminder.id); }, onSnooze: function(event) { Mojo.Log.info("$$$$$$$$ Reminder-assistant onSnooze: start: " + this.reminder.id); this.snoozed =true; this.closeAlert(); this.autoSnoozed = false; this.reminder.userClosed = true; this.reminder.scheduleStartTime = true; this.reissueAutoSnoozedAlerts(); Mojo.Log.info("$$$$$$$$ Reminder-assistant onSnooze: end: " + this.reminder.id); }, removeReminder: function() { Mojo.Log.info("$$$$$$$$ Reminder-assistant removeReminder: start: " + this.reminder.id); this.reminders.removeReminder(this.reminder.id); Mojo.Log.info("$$$$$$$$ Reminder-assistant removeReminder: end: " + this.reminder.id); }, scheduleAtStartTime: function(){ //Schedule the alarm to go off again at the start time if(this.reminder.scheduleStartTime && (new Date().getTime()) < this.reminder.time){ Mojo.Log.info("$$$$$$$$ Reminder-assistant scheduleAtStartTime: scheduling "+this.reminder.id+" for "+new Date(this.reminder.time)); this.controller.serviceRequest ("palm://com.palm.taskScheduler", { method : "updateTask" , parameters : { "arguments" : { id : "com.palm.app.calendar" , params: {alarmsnooze: this.reminder.id} } , key : "calendar-snooze-" + this.reminder.id , misfirePolicy : { executeNow: true } , prereq : [ "MSM_OFF" ] , start : { date: new Date(this.reminder.time).toUTCString() } , uri : "palm://com.palm.applicationManager/open" } }); } this.reminder.scheduleStartTime = false; }, snooze: function(minutes) { Mojo.Log.info("$$$$$$$$ Reminder-assistant snooze: start: " + this.reminder.id); if(this.autoSnoozed && this.reminder.userClosed === false) { //if autoSnoozed, let the reminder go to the missed reminders list without snoozing. Mojo.Log.info("$$$$$$$$ Reminder-assistant snooze: autosnoozed "+this.reminder.id); return; } var snooze = new Date().addMinutes(minutes); Mojo.Log.info("$$$$$$$$ Reminder-assistant snooze: updateTask: calendar-snooze-" + this.reminder.id + " date = " + snooze.toUTCString()); this.controller.serviceRequest ("palm://com.palm.taskScheduler", { method : "updateTask" , parameters : { "arguments" : { id : "com.palm.app.calendar" , params: {alarmsnooze: this.reminder.id} } , key : "calendar-snooze-" + this.reminder.id , misfirePolicy : { executeNow: true } , prereq : [ "MSM_OFF" ] , start : { date: snooze.toUTCString()} , uri : "palm://com.palm.applicationManager/open" } }); var templateModel = {}; var templateStr = $L("Snoozed for #{num} minutes"); templateModel.num =minutes; var template = new Template(templateStr); var snoozeText=template.evaluate(templateModel); Mojo.Log.info("$$$$$$$$ Reminder-assistant snooze: showBanner" + this.reminder.id); Mojo.Controller.appController.showBanner({messageText: snoozeText}, null /*launchArguments*/, "calendar-snooze"); Mojo.Log.info("$$$$$$$$ Reminder-assistant snooze: end" + this.reminder.id); }, closeAlert: function() { Mojo.Log.info("$$$$$$$$ Reminder-assistant closeAlert: start "); this.reminders.stopObservingReminders('alert'); Mojo.Log.info("$$$$$$$$ Reminder-assistant closeAlert: window.close() "); this.controller.window.close(); Mojo.Log.info("$$$$$$$$ Reminder-assistant closeAlert: end "); }, autoCloseAlert: function() { Mojo.Log.info("$$$$$$$$ Reminder-assistant autoCloseAlert: start" + this.reminder.id); this.dismissed = true; // prevent snooze this.closeAlert(); Mojo.Log.info("$$$$$$$$ Reminder-assistant autoCloseAlert: end " + this.reminder.id); }, specialCleanup:function(){ //we need to do this so that cleanup cleans the reminder rightaway Mojo.Log.info("$$$$$$$$ Reminder-assistant specialCleanup: window Name:" + this.controller.window.name); //we're auto-snoozing this because another reminder is being put up. this.controller.window.close(); this.autoSnoozed =true; }, showEventDetails: function() { this.controller.serviceRequest('palm://com.palm.applicationManager', { method: 'open', parameters: { 'id': 'com.palm.app.calendar', 'params': {'details': this.reminder.id.toString() } } }); }, scheduleAutoCloseTask: function() { Mojo.Log.info("$$$$$$$$ Reminder-assistant scheduleAutoCloseTask: start " + this.reminder.id); var minCloseTime= new Date(this.reminder.time).addMinutes(15); var closeTime = new Date(this.reminder.time + this.reminder.duration); if (closeTime < minCloseTime) { closeTime = minCloseTime; } Mojo.Log.info("$$$$$$$$ Reminder-assistant snooze: scheduleAutoCloseTask: calendar-alarmclose-" + this.reminder.id + " date = " + closeTime.toUTCString()); this.controller.serviceRequest ("palm://com.palm.taskScheduler", { method : "updateTask" , parameters : { "arguments" : { id : "com.palm.app.calendar" , params: { alarmclose: this.reminder.id } } , key : "calendar-alarmclose-" + this.reminder.id , misfirePolicy : { executeNow: true } , prereq : [ "MSM_OFF" ] , start : { date: closeTime.toUTCString() } , uri : "palm://com.palm.applicationManager/open" } }); Mojo.Log.info("$$$$$$$$ Reminder-assistant scheduleAutoCloseTask: end " + this.reminder.id); }, removeAutoCloseTask: function() { Mojo.Log.info("$$$$$$$$ Reminder-assistant removeAutoCloseTask: start " + this.reminder.id); Mojo.Log.info("$$$$$$$$ Reminder-assistant snooze: removeTask: calendar-alarmclose-" + this.reminder.id); this.controller.serviceRequest('palm://com.palm.taskScheduler', { method: 'removeTask', parameters: {key: 'calendar-alarmclose-'+this.reminder.id} }); Mojo.Log.info("$$$$$$$$ Reminder-assistant removeAutoCloseTask: end " + this.reminder.id); }, replaceHTML: function(element, content) { Mojo.Log.info("$$$$$$$$ Reminder-assistant replaceHTML:start"); var range = element.ownerDocument.createRange(); range.selectNode(element); content = range.createContextualFragment(content.stripScripts()); element.parentNode.replaceChild(content, element); Mojo.Log.info("$$$$$$$$ Reminder-assistant replaceHTML:end"); return element; }, updateHTML: function(element, content) { Mojo.Log.info("$$$$$$$$ Reminder-assistant updateHTML:start"); element.innerHTML = content; Mojo.Log.info("$$$$$$$$ Reminder-assistant updateHTML:end"); return element; } });