Updated system prefs patches
[webos-internals:imagineer1981s-modifications.git] / advanced / advanced-system-prefs-email-prefs.patch
1 --- .orig/usr/palm/applications/com.palm.app.email/app/models/AccountPreferences.js
2 +++ /usr/palm/applications/com.palm.app.email/app/models/AccountPreferences.js
3 @@ -33,6 +33,9 @@
4                 notifications: {
5                                                 enabled: emailAccount.notifications.enabled,
6                                                 type: emailAccount.notifications.type,
7 +                                               blink: emailAccount.notifications.blink,
8 +                                               repeatInterval: emailAccount.notifications.repeatInterval,
9 +                                               repeatLimit: emailAccount.notifications.repeatLimit,
10                                                 ringtoneName: emailAccount.notifications.ringtoneName,
11                                                 ringtonePath: emailAccount.notifications.ringtonePath
12                                         }
13 --- .orig/usr/palm/applications/com.palm.app.email/app/views/accountmanager/account-item.html
14 +++ /usr/palm/applications/com.palm.app.email/app/views/accountmanager/account-item.html
15 @@ -1,5 +1,6 @@
16  <div class="palm-row" x-mojo-tap-highlight="momentary" id="accountmanager_#{_id}" accountid="#{accountId}">
17    <div class="palm-row-wrapper">
18 +    <div class="notifications icon" x-mojo-tap-highlight="momentary"></div>
19      <div class="two-line">
20           <div id="account-icon-#{_id}" class="left palm-account-icon" style="background: url(#{iconPath})" ></div> 
21           <div class="domain-text truncating-text">
22 --- .orig/usr/palm/applications/com.palm.app.email/app/controllers/accountmanager-assistant.js
23 +++ /usr/palm/applications/com.palm.app.email/app/controllers/accountmanager-assistant.js
24 @@ -14,7 +14,7 @@
25         this.initialAccountNum = this.getNumberAccounts();
26         this.defaultAccountList = [];
27         this.currentDefaultAccount = null;
28 -       this.renderDefaultAccount = this.renderDefaultAccount.bind(this);
29 +//     this.renderDefaultAccount = this.renderDefaultAccount.bind(this);
30         this.deletionSettings = {
31                 confirmDeleteOnSwipe: !!EmailApp.prefs.get('confirmDeleteOnSwipe')
32         };
33 @@ -23,7 +23,7 @@
34  
35         AccountmanagerAssistant.prototype.activate = function() {
36                 //EmailApp.accounts.refresh(); // update list of configured accounts
37 -               this.renderDefaultAccount();
38 +//             this.renderDefaultAccount();
39                 // Clear the notification filters so user will get notified when any email comes in
40                 var notificationAssistant = Mojo.Controller.getAppController().assistant.notificationAssistant;
41                 notificationAssistant.setFilter();
42 @@ -54,7 +54,13 @@
43         
44         AccountmanagerAssistant.prototype.handleAccountTap = function(event) {
45                 // make sure to pass decorated account object from AccountsList. This allows proper scene setup for account type
46 -               this.controller.stageController.pushScene('accountpreferences', {account: EmailApp.accounts.ids[event.target.getAttribute('accountid')], type: "email" });
47 +               if(event.originalEvent.target.className == "notifications icon selected") {
48 +                       this.controller.stageController.pushScene('prefsSetupNotifications', event.target.getAttribute('accountid'));
49 +               }
50 +               else {
51 +                       // make sure to pass decorated account object from AccountsList. This allows proper scene setup for account type
52 +                       this.controller.stageController.pushScene('accountpreferences', {account: EmailApp.accounts.ids[event.target.getAttribute('accountid')], type: "email" });
53 +               }
54         };
55         
56         AccountmanagerAssistant.prototype.handleAddAccount = function(event) {
57 @@ -68,7 +74,7 @@
58         AccountmanagerAssistant.prototype.setup = function() {
59                 var controller = this.controller;
60                 this.delayActivate = true;
61 -               this.defaultAccountElement = this.controller.get('account-manager-default-account');
62 +//             this.defaultAccountElement = this.controller.get('account-manager-default-account');
63                 this.mainElement = this.controller.get('main');
64                 this.accountsErrorCount = 0;
65                 this.accountModel = {
66 @@ -76,8 +82,8 @@
67                         items: EmailApp.accounts.list
68                 };
69                 
70 -               Mojo.Event.listen(this.controller.stageController.document,
71 -                                                         Mojo.Event.stageActivate, this.renderDefaultAccount, true);
72 +//             Mojo.Event.listen(this.controller.stageController.document,
73 +//                                                       Mojo.Event.stageActivate, this.renderDefaultAccount, true);
74                 this.smartFolderPrefs = {
75                         allinboxes: { id: -1, value: EmailApp.prefs.get('showAllInboxes') },
76                         allflagged: { id: -1, value: EmailApp.prefs.get('showAllFlagged') },
77 @@ -116,7 +122,7 @@
78                 controller.listen('add-account-button', Mojo.Event.tap, this.handleAddAccount);
79                 
80                 
81 -               controller.listen('account-manager-default-account', Mojo.Event.tap, this.handleSelectDefaultAccount.bind(this));
82 +//             controller.listen('account-manager-default-account', Mojo.Event.tap, this.handleSelectDefaultAccount.bind(this));
83                 this._setupAccountsList();
84                 EmailApp.accounts.addListener(this.handleAccountsChanged);
85         };
86 @@ -204,7 +210,7 @@
87                                                 return (a - b); 
88                                         });
89         this.accountsChanged(mailAccts);
90 -       this.renderDefaultAccount();
91 +//     this.renderDefaultAccount();
92  };
93  
94         
95 @@ -233,13 +239,15 @@
96                 }
97                 
98                 EmailApp.AccountList.saveAccountOrder(freshList);
99 +               
100 +               EmailApp.prefs.set('defaultAccountId', freshList[0].accountId);
101         };
102         
103         /**
104          * event handler
105          * @param {Object} id
106          */
107 -       AccountmanagerAssistant.prototype.defaultAccountChanged = function(id) {
108 +/*     AccountmanagerAssistant.prototype.defaultAccountChanged = function(id) {
109                 // Don't do anything if this is already the default account
110                 if (id === undefined || this.currentDefaultAccount._id === id) {
111                         return;
112 @@ -254,12 +262,12 @@
113                 // update app preferences
114                 EmailApp.prefs.set('defaultAccountId', this.currentDefaultAccount._id);
115         };
116 -
117 +*/
118         AccountmanagerAssistant.prototype.cleanup = function() {
119                 EmailApp.accounts.removeListener(this.handleAccountsChanged);
120                 this.controller.stopListening('add-account-button', Mojo.Event.tap, this.handleAddAccount);
121 -               Mojo.Event.stopListening(this.controller.stageController.document,
122 -                                                         Mojo.Event.stageActivate, this.renderDefaultAccount, true);
123 +//             Mojo.Event.stopListening(this.controller.stageController.document,
124 +//                                                       Mojo.Event.stageActivate, this.renderDefaultAccount, true);
125  
126                 if (this.controller.stageController.setWindowOrientation) {
127                         this.controller.stageController.setWindowOrientation("free");
128 @@ -333,7 +341,7 @@
129                 EmailApp.prefs.set(propName, event.model.value);
130         };
131  
132 -       AccountmanagerAssistant.prototype.renderDefaultAccount = function () {
133 +/*     AccountmanagerAssistant.prototype.renderDefaultAccount = function () {
134                 // subscription succeeded so reset the failure count
135                 this.accountsErrorCount = 0;
136  
137 @@ -350,12 +358,14 @@
138                         
139                         if (activeScene && activeScene.sceneName === 'accountmanager') {
140                                 Mojo.Log.info('AccountmanagerAssistant: no accounts found, so push to wizard scene');
141 +*/
142                                 /* Somehow activate add-event of accounts UI widget here */
143 +/*
144                                 this.accountWidget.mojo.addAccount({displayText: $L("New Mail Account")});
145                         } 
146                         this.controller.get('sceneTitle').innerHTML = AccountmanagerAssistant.kTitleNoAccounts;
147                         this.controller.get('smart-folder-toggles').style.display='none';
148 -                       this.controller.get('account-manager-default-account-group').style.display='none';
149 +//                     this.controller.get('account-manager-default-account-group').style.display='none';
150                         return;
151                 }
152                 
153 @@ -391,7 +401,7 @@
154                         });
155                 }
156         };
157 -       
158 +*/     
159  AccountmanagerAssistant.prototype.deletionOptions = {
160         modelProperty: "confirmDeleteOnSwipe",
161         trueValue: true,
162 --- .orig/usr/palm/applications/com.palm.app.email/app/views/accountmanager/accountmanager-scene.html
163 +++ /usr/palm/applications/com.palm.app.email/app/views/accountmanager/accountmanager-scene.html
164 @@ -42,8 +42,11 @@
165         
166         <div id="account-display-list" class="edit_addremove accounts-list" x-mojo-element="List"></div>
167         <div id='accounts-list' x-mojo-element='AccountsList' style='display:none'></div>
168 +
169 +       <div x-mojo-loc="" class="palm-info-text">Emails created in “All Inboxes” view will default to the first account on the list.</div>
170 +
171         <div id="add-account-button" x-mojo-loc="" x-mojo-element="Button"></div>
172 -       <div id="account-manager-default-account-group">
173 +<!--   <div id="account-manager-default-account-group">
174                 <div class="palm-group">
175                         <div class="palm-group-title" x-mojo-loc=''>Default account</div>
176                         <div class="palm-list">
177 @@ -54,5 +57,5 @@
178                         </div>
179                 </div> 
180                 <div x-mojo-loc="" class="palm-info-text">New emails created in the “All Inboxes” view will default to this account.</div>
181 -       </div> 
182 -</div>
183 \ No newline at end of file
184 +       </div> -->
185 +</div>
186 --- .orig/usr/palm/applications/com.palm.app.email/app/controllers/accountpreferences-assistant.js
187 +++ /usr/palm/applications/com.palm.app.email/app/controllers/accountpreferences-assistant.js
188 @@ -14,7 +14,7 @@
189  var AccountpreferencesAssistant = function(params){
190         this.accountPrefs = AccountPreferences.getPrefsByAccountId(params.account._id);
191         this.accountPrefs.type = EmailApp.accounts.getAccountType(params.account._id);
192 -       this.accountPrefs.notifications = this.accountPrefs.notifications || {}; // ensure we have a notifications object, so we don't have to constantly check for it.
193 +//     this.accountPrefs.notifications = this.accountPrefs.notifications || {}; // ensure we have a notifications object, so we don't have to constantly check for it.
194         
195         this.account = params.account;
196         
197 @@ -43,10 +43,10 @@
198         Mojo.Log.warn("NOTE setup() for scene %s", this.controller.sceneName);  
199         
200         // bind functions
201 -       this.showNotificationChangeHandler = this.showNotificationChanged.bind(this);
202 +/*     this.showNotificationChangeHandler = this.showNotificationChanged.bind(this);
203         this.notificationTypeChangeHandler = this.notificationTypeChanged.bind(this);
204         this.chooseNotificationRingtone = this.chooseNotificationRingtone.bind(this);
205 -
206 +*/
207         this.imapServerSent = this.controller.get('imap-sent');
208         this.imapServerDrafts = this.controller.get('imap-drafts');
209         this.imapServerTrash = this.controller.get('imap-trash');
210 @@ -63,7 +63,7 @@
211         this.controller.setupWidget('edit-account-sync-lookback-selector', this.syncWindowOptions, this.accountPrefs);
212         this.controller.setupWidget('edit-account-sync-fetch-selector', this.fetchOptions, this.accountPrefs);
213         //this.controller.setupWidget('edit-account-mail-format-selector', this.mailFormats, this.accountPrefs);
214 -       this.controller.setupWidget('edit-account-show-notification-toggle', this.notificationOptions, this.accountPrefs.notifications);
215 +//     this.controller.setupWidget('edit-account-show-notification-toggle', this.notificationOptions, this.accountPrefs.notifications);
216         this.controller.setupWidget('sync-deleted-toggle', this.syncDeletedOptions, this.accountPrefs);
217         this.controller.setupWidget('sync-server-deleted-toggle', this.syncServerDeletedOptions, this.accountPrefs);
218         
219 @@ -91,8 +91,8 @@
220         this.handleEditAccountDetails = this.handleEditAccountDetails.bind(this);
221         this.controller.listen('edit-account-button', Mojo.Event.tap, this.handleEditAccountDetails);
222         this.controller.listen('delete-account-button', Mojo.Event.tap, this.handleRemoveAccount);
223 -       this.controller.listen('ringtone-row', Mojo.Event.tap, this.chooseNotificationRingtone);
224 -       this.controller.listen('edit-account-show-notification-toggle', Mojo.Event.propertyChange, this.showNotificationChangeHandler);
225 +//     this.controller.listen('ringtone-row', Mojo.Event.tap, this.chooseNotificationRingtone);
226 +//     this.controller.listen('edit-account-show-notification-toggle', Mojo.Event.propertyChange, this.showNotificationChangeHandler);
227  
228         // Listen for taps on the IMAP Server folders
229         this.controller.listen('edit-account-imap-sent', Mojo.Event.tap, this.handleChangeServerFolder.bind(this, "sent"));
230 @@ -165,10 +165,11 @@
231              this._renderImapFolders();
232          }
233          Mojo.Log.warn("NOTE: activate() for scene %s DONE", this.controller.sceneName);
234 -        var notificationAssistant = Mojo.Controller.getAppController().assistant.notificationAssistant;
235 +/*        var notificationAssistant = Mojo.Controller.getAppController().assistant.notificationAssistant;
236          if (notificationAssistant) {
237              notificationAssistant.setFilter();
238          }
239 +*/
240          if (this.controller.stageController.setWindowOrientation) {
241              this.controller.stageController.setWindowOrientation("up");
242          }
243 @@ -253,7 +254,7 @@
244  
245  AccountpreferencesAssistant.prototype.handleSaveAccount = function() {
246         // If the user turned off UI notifications for this account, clear any that is currently displayed 
247 -       if (this.accountPrefs.notifications.enabled === false) {
248 +/*     if (this.accountPrefs.notifications.enabled === false) {
249                 Mojo.Controller.getAppController().assistant.notificationAssistant.clear(this.account._id);
250         }
251         
252 @@ -263,7 +264,7 @@
253                         !this.accountPrefs.notifications.ringtonePath) {
254                 this.accountPrefs.notifications.type = AccountpreferencesAssistant.kNotifyTypeSystem;
255         }
256 -       
257 +*/     
258         // richtextedit doesn't use data model so manually copy the signature
259         var signature = this.controller.get('signature').innerHTML;
260         if (signature.length === 0) {
261 @@ -303,7 +304,7 @@
262                 object: account
263         });
264  };
265 -
266 +/*
267  AccountpreferencesAssistant.prototype.showNotificationChanged = function() {
268         var rowElem = this.controller.get("show_notification-row");
269         if (this.accountPrefs.notifications.enabled !== false) {
270 @@ -347,7 +348,7 @@
271         this.accountPrefs.notifications.ringtonePath = file.fullPath;
272         this.controller.get('current-ringtone').innerHTML = file.name;
273  };
274 -
275 +*/
276  AccountpreferencesAssistant.prototype.saveSuccess = function() {
277         var message = $L("Preferences updated");
278         Mojo.Controller.getAppController().assistant.notificationAssistant.generalNotification(message);
279 @@ -385,7 +386,7 @@
280  };
281  
282  AccountpreferencesAssistant.prototype.renderAccountDetails = function() {
283 -       this.accountPrefs.notifications.showRingtoneButton = this.accountPrefs.notifications.type === AccountpreferencesAssistant.kNotifyTypeRingtone;
284 +//     this.accountPrefs.notifications.showRingtoneButton = this.accountPrefs.notifications.type === AccountpreferencesAssistant.kNotifyTypeRingtone;
285         
286         // Set the title icon
287         Mojo.Log.error("Setting the title icon");
288 @@ -458,7 +459,7 @@
289         Mojo.Event.listen(signatureElem, 'blur', function() { Mojo.Dom.removeClassName(signatureElem, 'focused'); }, true);
290  
291         // Setup the drawer here so that it doesn't animate once the scene is rendered
292 -       this.controller.setupWidget('sound-toggle-drawer', {unstyled:true, property:'enabled'}, this.accountPrefs.notifications);
293 +/*     this.controller.setupWidget('sound-toggle-drawer', {unstyled:true, property:'enabled'}, this.accountPrefs.notifications);
294         this.controller.setupWidget('sound-selector', this.soundOptions, this.accountPrefs.notifications);
295         this.controller.setupWidget('ringtone-drawer', {unstyled:true, property:'showRingtoneButton'}, this.accountPrefs.notifications);
296         this.controller.instantiateChildWidgets(this.controller.get('drawer-container'));
297 @@ -468,7 +469,7 @@
298  
299         // Update the UI now (this calls modelChanged)
300         this.showNotificationChanged();
301 -       
302 +*/     
303         if (this.readyToActivateCallback) {
304                 this.readyToActivateCallback();
305                 this.readyToActivateCallback = null;
306 @@ -505,13 +506,13 @@
307  //             {label: $L('Plain text'), value: 0}
308  //     ]
309  //};
310 -
311 +/*
312  AccountpreferencesAssistant.prototype.notificationOptions = {
313         modelProperty: "enabled",
314         trueValue: true,
315         falseValue: false
316  };
317 -
318 +*/
319  AccountpreferencesAssistant.prototype.syncWindowOptions = {
320      multiline: true,
321         modelProperty: 'syncWindowDays',
322 @@ -525,7 +526,7 @@
323                 {label: $L('All'), value: "0"}
324         ]
325  };
326 -
327 +/*
328  AccountpreferencesAssistant.prototype.soundOptions = {
329         multiline: true,
330         modelProperty: 'type',
331 @@ -537,7 +538,7 @@
332                 {label: $L("Mute"), value: AccountpreferencesAssistant.kNotifyTypeMute}
333         ]
334  };
335 -
336 +*/
337  AccountpreferencesAssistant.prototype.syncDeletedOptions = {
338         modelProperty: "deleteFromServer",
339         trueValue: true,
340 --- .orig/usr/palm/applications/com.palm.app.email/app/views/accountpreferences/accountpreferences-scene.html
341 +++ /usr/palm/applications/com.palm.app.email/app/views/accountpreferences/accountpreferences-scene.html
342 @@ -41,7 +41,7 @@
343             <div id="edit-account-mail-format-selector" class="row single" x-mojo-element="ListSelector"></div>
344         </div>
345  </div-->
346 -
347 +<!--
348  <div class="palm-group">
349         <div class="palm-group-title" x-mojo-loc=''>New Message</div>
350         <div id="edit-account-new-message-list" class="palm-list">
351 @@ -70,6 +70,19 @@
352                 </div>
353         </div>
354  </div>
355 +-->
356 +<div id="edit-account-reply-to" class="palm-group">
357 +       <div class="palm-group-title" x-mojo-loc=''>Reply-To Address</div>
358 +       <div id="edit-account-reply-to-list" class="palm-list">
359 +               <div class="palm-row single">
360 +                       <div class="palm-row-wrapper textfield-group" x-mojo-focus-highlight="true">
361 +                               <div class="title">
362 +                                       <div id="reply-to" x-mojo-element="TextField"></div>          
363 +                               </div>
364 +                       </div>
365 +               </div>
366 +       </div>
367 +</div>
368  
369  <div id="edit-account-signature" class="palm-group">
370         <div class="palm-group-title" x-mojo-loc=''>Signature</div>
371 @@ -84,19 +97,6 @@
372         </div> 
373  </div>
374  
375 -<div id="edit-account-reply-to" class="palm-group">
376 -       <div class="palm-group-title" x-mojo-loc=''>Reply-To Address</div>
377 -       <div id="edit-account-reply-to-list" class="palm-list">
378 -               <div class="palm-row single">
379 -                       <div class="palm-row-wrapper textfield-group" x-mojo-focus-highlight="true">
380 -                               <div class="title">
381 -                                       <div id="reply-to" x-mojo-element="TextField"></div>          
382 -                               </div>
383 -                       </div>
384 -               </div>
385 -       </div>
386 -</div>
387 -
388  <!-- Sync settings -->
389  <div id="edit-account-sync" class="palm-group">
390         <div class="palm-group-title" x-mojo-loc=''>Sync</div>
391 --- .orig/usr/palm/applications/com.palm.app.email/app/controllers/app-assistant.js
392 +++ /usr/palm/applications/com.palm.app.email/app/controllers/app-assistant.js
393 @@ -20,12 +20,12 @@
394         // This is primarily to load the email depot so it doesn't need to be loaded later
395         this.depot = EmailAppDepot.getDepot();
396         
397 -       // Send list of localized strings to the service.
398 -       //ServiceStrings.sendLocalizedStrings();
399 -       
400         // Startup NotificationAssistant
401         this.notificationAssistant = new NotificationAssistant(appController);
402  
403 +       // Send list of localized strings to the service.
404 +       //ServiceStrings.sendLocalizedStrings();
405 +       
406         // this is used to debounce the launch requests in case the user impatiently
407         // taps on a banner notification
408         this.debounceIds = {};
409 @@ -72,6 +72,10 @@
410                                                                                 },
411                                                                 syncronizer.wrap(Mojo.doNothing));
412         
413 +               
414 +       // Load contacts.
415 +       EmailApp.emails = new EmailApp.Util.MojoDBEmails('com.palm.person:1', syncronizer.wrap(Mojo.doNothing));
416 +
417         // Configure initial carrier defaults, and load/reload them from the db as needed:
418         this.kDefaultCarrierDefaults = {
419                 defaultSignature: EmailAccount.addStylingToSig(ServiceStrings.stringsNeededByService.defaultSignature)
420 @@ -463,6 +467,9 @@
421         
422         LaunchHandler.prototype.handleLaunch = function() {
423                 var params = this.launchParameters;
424 +               
425 +               this.notificationAssistant.removePlayNotificationSoundTasks();          
426 +
427                 if (params.securityPolicyError) {
428                         this.handleSecurityPolicyError(params);
429                 } else if (params.certificateError) {
430 @@ -481,11 +488,21 @@
431                         this.handleEditAccount();
432                 } else if (params.reminderPersonId) { 
433                         this.handleContact(params);
434 +               } else if (params.playNotificationSound) {
435 +                       // Delay playing to go around WebOS bug (sound not playing).
436 +
437 +                       setTimeout(this.playNotificationSound.bind(this, params.accountId), 1000);
438                 } else {
439                         this.handleDefault();
440                 }
441         };
442         
443 +       LaunchHandler.prototype.playNotificationSound = function(accountId) {
444 +               this.notificationAssistant.playNotificationSound(accountId);
445 +                       
446 +               this.notificationAssistant.schedulePlayNotificationSoundTasks(accountId);
447 +       };
448 +       
449         LaunchHandler.prototype.handleCompose = function() {
450                 var params = this.launchParameters;
451                 var mailToURL = params.uri || params.target;
452 --- .orig/usr/palm/applications/com.palm.app.email/stylesheets/email.css
453 +++ /usr/palm/applications/com.palm.app.email/stylesheets/email.css
454 @@ -109,6 +109,17 @@
455         color:#555555; /*gray*/
456  }
457  
458 +.palm-row .notifications.icon {
459 +       float: right;
460 +       display: block;
461 +       margin: 1px 3px -1px 0px;
462 +       background: url(../images/icon-notifications.png) top right no-repeat;
463 +       width: 60px;
464 +       height: 50px;
465 +}
466 +
467 +.notifications.icon.selected { background-position: bottom right; }
468 +
469  /* folder-list unread pill */
470  .folder-list-unread-container {
471         text-align:right;
472 @@ -429,6 +440,11 @@
473      background: url(../images/account-generic-small.png) center center no-repeat;
474  }
475  
476 +.palm-row .palm-account-icon {
477 +    background: url(../images/account-generic-small.png) center center no-repeat;
478 +    margin: 5px 10px 0px 2px;
479 +}
480 +
481  /**************************************************************************************************
482   *
483   * email read-view (message) specifics
484 --- .orig/usr/palm/applications/com.palm.app.email/app/controllers/notification-assistant.js
485 +++ /usr/palm/applications/com.palm.app.email/app/controllers/notification-assistant.js
486 @@ -39,6 +39,10 @@
487         this.pending = {};
488         this.dashboards = {};
489         this.errorDashboards = {};
490 +       this.notificationsData = {};
491 +       this.newEmails = [];
492 +       
493 +       this.notifyTimeout = null;
494         
495         this.windowActivate = this.windowActivate.bind(this);
496         this._handleNewEmails = this._handleNewEmails.bind(this);
497 @@ -106,7 +110,6 @@
498  NotificationAssistant.prototype._handleNewEmails = function(emails) {
499         var maxRev = 0, count;
500         var i;
501 -       var notifications;
502         
503         // Update showAllInboxes, in case it changed.
504         this.showAllInboxes = EmailApp.prefs.get('showAllInboxes');
505 @@ -128,8 +131,26 @@
506         for(i=0; i<emails.length; i++) {
507                 emails[i].accountId = this.appController.assistant.getEmailAccount(emails[i]);
508         }
509 +
510 +       this.newEmails = this.newEmails.concat(emails);
511 +
512 +       if(this.notifyTimeout)
513 +               clearTimeout(this.notifyTimeout);
514 +
515 +       // Make sure that the device wont go to sleep until alert is handled
516 +
517 +       this.activityRequest = new Mojo.Service.Request("palm://com.palm.power/com/palm/power", {
518 +    'method': "activityStart", 'parameters': {'id': Mojo.Controller.appInfo.id,
519 +    'duration_ms': 15000} });
520         
521 +       this.notifyTimeout = setTimeout(this._processNewEmails.bind(this), 5000);
522 +}
523 +
524 +NotificationAssistant.prototype._processNewEmails = function() {       
525 +       var emails = this.newEmails.slice(0);
526         
527 +       this.newEmails = [];
528 +
529         // Filter out anything we don't currently care about:
530         count = emails.length;
531         emails = _.select(emails, this._shouldNotify, this);
532 @@ -140,13 +161,40 @@
533         emails.forEach(this._addNewEmail, this);        
534         
535         // Build a list of accounts with new emails, and then map the "play sound for account" function over them.
536 -       notifications = {};
537 -       emails.forEach(function(email) {notifications[email.accountId] = true;}, this); 
538 -       _.map(_.keys(notifications), this._doNotificationForAccount, this);
539         
540 -       // Make our dashboards reflect the data. 
541 -       this._updateDirtyDashboards();
542 +       var allUnknown = true;
543         
544 +       var notifications = {};
545 +       
546 +       emails.forEach(function(email) {
547 +               if(EmailApp.emails.check(email.from.addr))
548 +                       allUnknown = false;
549 +               
550 +               notifications[email.accountId] = true;
551 +       }, this);       
552 +
553 +       if(allUnknown) {
554 +               if(this.contactPrefs)
555 +                       delete this.contactPrefs;
556 +       
557 +               this.contactPrefs = new window.Contacts.AppPrefs(function() {
558 +                       var prefs = this.contactPrefs.get(Contacts.AppPrefs.Pref.unknownContacts);
559 +
560 +                       if((!prefs) || (!prefs.emailAlert) || (prefs.emailAlert == "default"))
561 +                               _.map(_.keys(notifications), this._doNotificationForAccount, this);
562 +                       else 
563 +                               this._doNotificationForUnknown(prefs.emailAlert, prefs.emailRingtonePath);
564 +                       
565 +                       // Make our dashboards reflect the data. 
566 +                       this._updateDirtyDashboards();
567 +               }.bind(this));
568 +       }
569 +       else {
570 +               _.map(_.keys(notifications), this._doNotificationForAccount, this);
571 +
572 +               // Make our dashboards reflect the data. 
573 +               this._updateDirtyDashboards();
574 +       }
575  };
576  
577  
578 @@ -332,6 +380,8 @@
579  // Update the dashboard for the given accountId (or the unified one if unspecified) to display the given message,
580  // creating it if necessary.
581  NotificationAssistant.prototype._updateDashboard = function(accountId, messages) {
582 +       var blinkNotify = false;
583 +
584         var db = this.dashboards[accountId];
585         
586         if(messages.length > 0) {
587 @@ -347,16 +397,44 @@
588                 var lastMessage = messages[messages.length-1];
589                 Mojo.Log.info("Updating  dashboard... textLen:%s, titleLen:%d, icon:%s", lastMessage.text && lastMessage.text.length, lastMessage.title && lastMessage.title.length, lastMessage.icon);
590                 
591 +               if(accountId == this.kUnifiedAccountId) {
592 +                       for(var accId in this.notificationsData) {
593 +                               var accData = EmailApp.accounts.mailAccounts[accId];
594 +
595 +                               if((accData) && (accData.notifications) && (accData.notifications.blink)) {
596 +                                       blinkNotify = true;
597 +                                       break;
598 +                               }
599 +                       }
600 +               }
601 +               else {
602 +                       var accData = EmailApp.accounts.mailAccounts[accountId];
603 +
604 +                       if((accData) && (accData.notifications) && (accData.notifications.blink))
605 +                               blinkNotify = true;
606 +               }
607 +
608 +               var stageName = NotificationAssistant.kNewEmailDashboardStageName+accountId;
609 +               
610                 // Update the dashboard content:
611                 if(db) {
612                         Mojo.Log.info("Updating dashboard for account %s, %d messages.", accountId, messages.length);
613                         db.show(messages);
614 +
615 +                       var stageController = this.appController.getStageController(stageName);
616 +
617 +                       if((stageController) && (blinkNotify))
618 +                               stageController.indicateNewContent(true);
619                 } else {
620                         Mojo.Log.info("Creating dashboard for account %s, %d messages.", accountId, messages.length);
621 -                       db = this.appController.createDashboard(NotificationAssistant.kNewEmailDashboardStageName+accountId, messages, {
622 +                       db = this.appController.createDashboard(stageName, messages, {
623                                 mainTapHandler: this._dashboardMainTap.bind(this, accountId),
624                                 iconTapHandler: this._dashboardIconTap.bind(this, accountId),
625 -                               cleanup: this._dashboardClosed.bind(this, accountId)
626 +                               cleanup: this._dashboardClosed.bind(this, accountId),
627 +                               onSuccess: function(blinkNotify, sceneController){
628 +                                       if(blinkNotify)
629 +                                               sceneController.stageController.indicateNewContent(true);
630 +                               }.bind(this, blinkNotify)
631                         });
632                                 /* 
633                                 {
634 @@ -460,6 +538,10 @@
635         if(messages) {
636                 messages.length = 0;
637         }
638 +
639 +       this.removePlayNotificationSoundTasks();
640 +
641 +       this.notificationsData = {};
642         
643         Mojo.Log.info("NotificationAssistant._dashboardClosed for account ", accountId);
644  };
645 @@ -592,18 +674,28 @@
646         
647         Mojo.Log.info("_doNotificationForAccount %s: ", accountId, notifType);
648         
649 -       if (notifType === AccountpreferencesAssistant.kNotifyTypeSystem) {
650 -               this.appController.playSoundNotification("notification");
651 -       } else if (notifType === AccountpreferencesAssistant.kNotifyTypeRingtone) {
652 -               this.appController.playSoundNotification("alerts", notifPrefs.ringtonePath);
653 +       if (notifType === AccountpreferencesAssistant.kNotifyTypeRingtone) {
654 +               this.appController.playSoundNotification("notifications", notifPrefs.ringtonePath);
655 +       } else if (notifType === AccountpreferencesAssistant.kNotifyTypeSystem) {
656 +               this.appController.playSoundNotification("notifications");
657         } else if (notifType === AccountpreferencesAssistant.kNotifyTypeVibrate) {
658 -               PalmSystem.playSoundNotification("vibrate");
659 +               this.appController.playSoundNotification("vibrate");
660         }
661         // No need to check for AccountpreferencesAssistant.kNotifyTypeMute, since mute is what happens if we don't do anything.
662         
663 +       this.schedulePlayNotificationSoundTasks(accountId);
664 +       
665         return; 
666  };
667  
668 +NotificationAssistant.prototype._doNotificationForUnknown = function(notifType, ringtonePath) {
669 +       if(notifType === AccountpreferencesAssistant.kNotifyTypeRingtone)
670 +               this.appController.playSoundNotification("notifications", ringtonePath);
671 +       else if(notifType === AccountpreferencesAssistant.kNotifyTypeSystem)
672 +               this.appController.playSoundNotification("notifications");
673 +       else if(notifType === AccountpreferencesAssistant.kNotifyTypeVibrate)
674 +               this.appController.playSoundNotification("vibrate");
675 +};
676  
677  // Utility for display of general notifications in a transient banner.
678  NotificationAssistant.prototype.generalNotification = function(msg) {
679 @@ -631,18 +723,27 @@
680         // send errors use alert icon, from fw: ../images/notification-alert.png
681         // Others use account icon
682         
683 +       var stageName = NotificationAssistant.kErrorDashboardStageName+accountId;
684 +       
685         if(!db) {
686                 Mojo.Log.error("Creating error dashboard for account %s: %s, %s", accountId, details.title, details.text);
687                 tapHandler = this._errorTapper.bind(this, accountId);
688 -               db = this.appController.createDashboard(NotificationAssistant.kErrorDashboardStageName+accountId, [details], {
689 +               db = this.appController.createDashboard(stageName, [details], {
690                         mainTapHandler: tapHandler,
691 -                       iconTapHandler: tapHandler
692 +                       iconTapHandler: tapHandler,
693 +                       onSuccess: function(accountId, sceneController){
694 +                               sceneController.stageController.indicateNewContent(true);
695 +                       }.bind(this, accountId)                 
696                 });
697                 this.errorDashboards[accountId] = db;
698         } else {
699                 db.pushContent(details);
700 +               
701 +               var stageController = this.appController.getStageController(stageName);
702 +               
703 +               if(stageController)
704 +                       stageController.indicateNewContent(true);
705         }
706 -       
707  };
708  
709  // Generic tap handler for all error dashboards.  Bound to handle both iconTap and mainTap.
710 @@ -768,8 +869,87 @@
711         }
712  };
713  
714 +NotificationAssistant.prototype.schedulePlayNotificationSoundTasks = function(accountId) {
715 +       var accData = EmailApp.accounts.mailAccounts[accountId];
716 +       
717 +       if((!accData) || (!accData.notifications) || (accData.notifications.enabled == false) ||
718 +               (accData.notifications.type == "mute") || (accData.notifications.repeatInterval == 0))
719 +       {
720 +               if(this.notificationsData[accountId])
721 +                       delete this.notificationsData[accountId];
722 +               
723 +               return;
724 +       }
725  
726 +       if(this.notificationsData[accountId] == undefined)
727 +               this.notificationsData[accountId] = 0;
728 +       
729 +       if(this.notificationsData[accountId]++ >= accData.notifications.repeatLimit) {
730 +               delete this.notificationsData[accountId];
731 +               
732 +               return;
733 +       }
734 +       
735 +       // Reset all notifications to synchronize the notification events.
736 +       
737 +       var delay = 0;
738 +
739 +       var currentTime = new Date();
740 +       
741 +       for(var accountId in this.notificationsData) {
742 +               var accData = EmailApp.accounts.mailAccounts[accountId];
743  
744 +               if((accData) && (accData.notifications) && (accData.notifications.enabled != false) &&
745 +                       (accData.notifications.type != "mute") || (accData.notifications.repeatInterval != 0))
746 +               {
747 +                       var repeatInterval = accData.notifications.repeatInterval;
748 +               
749 +                       var playSoundTime = new Date(currentTime.getTime() + (parseInt(repeatInterval) * 1000) + (delay++ * 10));
750 +
751 +                       var month = playSoundTime.getUTCMonth()+1;
752 +                       if(month < 10) month = "0" + month;
753 +                       var day = playSoundTime.getUTCDate();
754 +                       if(day < 10) day = "0" + day;
755 +                       var year = playSoundTime.getUTCFullYear();
756 +
757 +                       var hours = playSoundTime.getUTCHours();
758 +                       if(hours < 10) hours = "0" + hours;
759 +                       var minutes = playSoundTime.getUTCMinutes();
760 +                       if(minutes < 10) minutes = "0" + minutes;
761 +                       var seconds = playSoundTime.getUTCSeconds();
762 +                       if(seconds < 10) seconds = "0" + seconds;
763 +
764 +                       var scheduledTimeStr = month + "/" + day + "/" + year + " " + hours + ":" + minutes + ":" + seconds;
765 +               
766 +                       this.updateTimeoutRequest = new Mojo.Service.Request('palm://com.palm.power/timeout/', {
767 +                               'method': "set", 'parameters': { 'key': 'emailPlayNotificationSound-' + accountId, 
768 +                               'wakeup': true, 'at': scheduledTimeStr, 'uri': "palm://com.palm.applicationManager/open", 
769 +                               'params': {'id': 'com.palm.app.email', 'params': {'accountId': accountId,
770 +                                       'playNotificationSound': this.notificationsData[accountId]}}} }); 
771 +               }
772 +       }
773 +};
774 +       
775 +NotificationAssistant.prototype.removePlayNotificationSoundTasks = function() {
776 +       for(var accountId in this.notificationsData) {
777 +               this.removeTimeoutRequest = new Mojo.Service.Request("palm://com.palm.power/timeout/", {
778 +                       'method': "clear", 'parameters': {"key": 'emailPlayNotificationSound-' + accountId} });
779 +       }
780 +};
781 +
782 +NotificationAssistant.prototype.playNotificationSound = function(accountId) {
783 +       var accData = EmailApp.accounts.mailAccounts[accountId];
784 +       
785 +       if((accData) && (accData.notifications) && (accData.notifications.enabled == true)) {
786 +               if(accData.notifications.type === AccountpreferencesAssistant.kNotifyTypeRingtone)
787 +                       this.appController.playSoundNotification("notifications", accData.notifications.ringtonePath);
788 +               else if(accData.notifications.type === AccountpreferencesAssistant.kNotifyTypeSystem)
789 +                       this.appController.playSoundNotification("notifications");
790 +               else if(accData.notifications.type === AccountpreferencesAssistant.kNotifyTypeVibrate)
791 +                       this.appController.playSoundNotification("vibrate");
792 +       }
793 +};
794 +       
795  
796  /*
797  NotificationAssistant.prototype.handleNewEmailNotification = function(list) {
798 --- .orig/usr/palm/applications/com.palm.app.email/sources.json
799 +++ /usr/palm/applications/com.palm.app.email/sources.json
800 @@ -33,6 +33,9 @@
801      "source": "app\/controllers\/accountpreferences-assistant.js"
802    },
803    {
804 +    "source": "app\/controllers\/prefsSetupNotifications-assistant.js"
805 +  },
806 +  {
807      "source": "app\/controllers\/app-assistant.js"
808    },
809    {
810 --- .orig/usr/palm/applications/com.palm.app.email/javascripts/util.js
811 +++ /usr/palm/applications/com.palm.app.email/javascripts/util.js
812 @@ -414,6 +414,65 @@
813         return;
814  };
815  
816 +/******************************************************************************
817 +       Loads and manages changes to a persons email objects, stored in MojoDB.
818 +       
819 +       The object's "ready" property will be true once initialization is complete.
820 + ******************************************************************************/
821 +EmailApp.Util.MojoDBEmails = function(kind, onReady) {
822 +       this.ready = false; // set to true after we've loaded contact emails.
823 +
824 +       this._kind = kind;
825 +       this._onReady = onReady;
826 +
827 +       this._handleResult = this._handleResult.bind(this);
828 +       
829 +       this._doQuery();
830 +};
831 +
832 +
833 +EmailApp.Util.MojoDBEmails.prototype._doQuery = function() {
834 +       this._request = new Mojo.Service.Request('palm://com.palm.db/', {"method": 'find', "parameters": {
835 +               query: {from:this._kind}, watch: true}, onSuccess: this._handleResult.bind(this)});
836 +};
837 +
838 +EmailApp.Util.MojoDBEmails.prototype._handleResult = function(result) {
839 +       if(result.fired) {
840 +               this._doQuery();
841 +       }
842 +       else {
843 +               var emails = [];
844 +       
845 +               for(var i = 0; i < result.results.length; i++) {
846 +                       if(result.results[i].emails) {
847 +                               for(var j = 0; j < result.results[i].emails.length; j++) {
848 +                                       if(result.results[i].emails[j].value)
849 +                                               emails.push(result.results[i].emails[j].value);
850 +                               }
851 +                       }
852 +               }
853 +
854 +               this._emails = emails;
855 +               this.ready = true;
856 +       
857 +               Mojo.Log.info("MojoDBEmails: Emails loaded for ", this._kind);
858 +       
859 +               if(this._onReady) {
860 +                       this._onReady();
861 +                       this._onReady = undefined;
862 +               }
863 +       }
864 +};
865 +
866 +EmailApp.Util.MojoDBEmails.prototype.check = function(email) {
867 +       for(var i = 0; i < this._emails.length; i++) {
868 +               if(this._emails[i] == email)
869 +                       return true;
870 +       }
871 +
872 +       return false;
873 +};
874 +
875  /**
876   * Function to pretty print an object with a label.
877   * Allows deeper insight into an object than Mojo.Log.__("%j", foo);