ae3dab76c29aedcf47932448c1450e45a7c0a282
[apps/web/sample/ContactsExchanger.git] / project / js / app.ui.js
1 /*
2  *      Copyright 2013  Samsung Electronics Co., Ltd
3  *
4  *      Licensed under the Flora License, Version 1.1 (the "License");
5  *      you may not use this file except in compliance with the License.
6  *      You may obtain a copy of the License at
7  *
8  *              http://floralicense.org/license/
9  *
10  *      Unless required by applicable law or agreed to in writing, software
11  *      distributed under the License is distributed on an "AS IS" BASIS,
12  *      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *      See the License for the specific language governing permissions and
14  *      limitations under the License.
15  */
16
17 /*jslint devel: true*/
18 /*global $, tizen, App, app, localStorage: true, TemplateManager,document */
19 /*global window, setTimeout */
20
21 App.Ui = null;
22
23 (function () { // strict mode wrapper
24     'use strict';
25
26     App.Ui = function App_Ui(app) {
27         this.app = app;
28         this.templateManager = new TemplateManager(app.config);
29     };
30
31     App.Ui.prototype = {
32         prepareCallerName: function ui_prepareCallerName(contact) {
33             var name = contact.name.displayName;
34             return (name && name.length > 0) ? name : 'No Name';
35         },
36
37         /**
38          * Show a popup
39          * @param {string} message
40          */
41         showPopup: function ui_showPopup(message) {
42             var popup = $('#alertPopup');
43             if (!popup.hasClass('ui-popup')) {
44                 popup.popup().trigger('create');
45             }
46             $('.ui-popup-text', popup).text(message);
47             popup.popup('open', {
48                 positionTo: 'window'
49             });
50         },
51
52         closePopup: function ui_closePopup() {
53             var activePopup = $.mobile.popup.active;
54             if (activePopup) {
55                 if (activePopup.attr('id') === 'alertPopup') {
56                     activePopup.close();
57                 }
58             }
59         },
60
61         createListRecord: function ui_createListRecord() {
62             $.mobile.changePage('#choose');
63         },
64
65         /**
66          *
67          * @param {string} text
68          * @returns {string}
69          */
70         getWaitingContentHtml: function getWaitingContentHtml(text) {
71             var html;
72             html += '<p class="defaultVeryBigText">';
73             html += text;
74             html += '</p>';
75
76             html += '<p class="defaultCounterText" id="counter"></p>';
77
78             return html;
79         },
80
81         /**
82          *
83          * @param {string} title
84          * @param {string} text
85          */
86         prepareWaitingPage: function ui_prepareWaitingPage(title, text) {
87             var waitingBox, waitingContent,
88                 contentTransfer = $('#content-transfer');
89             waitingBox = $('<div class="box" id="waitingBox"></div>');
90             waitingContent = $(this.getWaitingContentHtml(text));
91             $('#header-transfer H1').text(title);
92             contentTransfer.empty();
93             waitingBox.append(waitingContent);
94             contentTransfer.append(waitingBox);
95             $('#content-start').trigger('create');
96             this.app.countDown(10, $('#counter'));
97         },
98
99         /**
100          * @returns {string}
101          */
102         getTemporaryBoxHtml: function ui_getTemporaryBoxHtml() {
103             return '<div class="box" id="temporaryBox"></div>';
104         },
105
106         /**
107          * @returns {string}
108          */
109         showPopupWarning: function ui_showPopupWarning() {
110             setTimeout(function () {
111                 $('#contact-nfc-error').popup('open', {
112                     'positionTo': 'window'
113                 });
114             }, 500);
115         },
116
117         getTemporaryBoxContentHtml: function ui_getTemporaryBoxContentHtml() {
118             return '<p class="defaultText">'
119                 + 'Default card is not defined yet!<br/>'
120                 + 'Do you want to define it now?' + '</p>';
121         },
122
123         loadTemporaryContent: function ui_loadTemporaryContent() {
124             var temporaryBox, temporaryContent, temporaryButton;
125
126             temporaryBox = $(this.getTemporaryBoxHtml());
127             temporaryContent = $(this.getTemporaryBoxContentHtml());
128             temporaryButton = $(this.getButtonHtml('Create default card'));
129
130             temporaryButton.on('click', function (event) {
131                 event.preventDefault();
132                 $.mobile.changePage('#choose');
133             });
134
135             temporaryBox.append(temporaryContent).append(temporaryButton);
136
137             $('#content-start').empty().append(temporaryBox).trigger('create');
138         },
139         /**
140          *
141          * @param {string} text button text
142          * @returns {string}
143          */
144         getButtonHtml: function ui_getButtonHtml(text) {
145             return '<div data-role="button" class="ui-btn-create">'
146                 + text + '</div>';
147         },
148
149         /**
150          *
151          * @param {string} firstName
152          * @param {string} lastName
153          * @returns {string}
154          */
155         getCommentHtml: function ui_getCommentHtml(data) {
156             var def_name = $('<p class="comment" id="comment-name">')
157                 .text(data.caller).html();
158             return '<div id="comment">'
159                 + '<p class="comment">Your default contact</p>'
160                 + '<p class="comment" id="comment-userName">'
161                 + def_name + '</p>' + '<p class="comment" id="comment-phone">'
162                 + data.phoneNumber + '</p>' + '</div>';
163         },
164
165
166         /**
167          * Change Contact button action
168          * @event
169          * @param {Event} event
170          */
171         changeContact: function ui_changeContact(event) {
172             event.preventDefault();
173             $.mobile.changePage('#choose');
174         },
175
176         /**
177          * @returns {jQuery}
178          */
179         getChangeContactButton: function ui_getChangeContactButton() {
180             var changeContactButton;
181             changeContactButton =
182                 $(this.getButtonHtml('Change your default contact'));
183             changeContactButton.on('click', this.changeContact);
184             return changeContactButton;
185         },
186
187         /**
188          * Read From Card button action
189          * @event
190          * @param {Event} event
191          */
192         readFromCard: function ui_readFromCard(event) {
193             event.preventDefault();
194             if (tizen.nfc.getDefaultAdapter().powered) {
195                 try {
196                     $('#transfer').data('option', 'read');
197                     $.mobile.changePage('#transfer');
198                 } catch (e) {
199                     console.error(e.message);
200                 }
201             } else {
202                 $.mobile.changePage('#start');
203                 alert('Please turn on NFC adapter');
204             }
205         },
206
207         /**
208          * @returns {jQuery}
209          */
210         getReadFromCardButton: function ui_getReadFromCardButton() {
211             var readFromCardButton;
212             readFromCardButton = $(this.getButtonHtml('Read from card'));
213             readFromCardButton.on('click', this.readFromCard);
214             return readFromCardButton;
215         },
216
217         /**
218          * Write To Card button action
219          * @param {Event} event
220          */
221         writeToCard: function ui_writeToCard(event) {
222             event.preventDefault();
223             if (tizen.nfc.getDefaultAdapter().powered) {
224                 try {
225                     $('#transfer').data('option', 'write');
226                     $.mobile.changePage('#transfer');
227                 } catch (e) {
228                     console.error(e.message);
229                 }
230             } else {
231                 alert('Please turn on NFC adapter');
232             }
233         },
234
235         /**
236          * @returns {jQuery}
237          */
238         getWriteToCardButton: function ui_getWriteToCardButton() {
239             var writeToCardButton;
240             writeToCardButton = $(this.getButtonHtml('Write to card'));
241             writeToCardButton.on('click', this.writeToCard);
242             return writeToCardButton;
243         },
244
245         /**
246          * Communicate With Other Device button action
247          * @param {type} event
248          */
249         commWithOtherDevice: function ui_commWithOtherDevice(event) {
250             event.preventDefault();
251             if (tizen.nfc.getDefaultAdapter().powered) {
252                 try {
253                     $('#transfer').data('option', 'communicate');
254                     $.mobile.changePage('#transfer');
255                 } catch (e) {
256                     console.error(e.message);
257                 }
258             } else {
259                 alert('Please turn on NFC adapter');
260             }
261         },
262
263         /**
264          * @returns {jQuery}
265          */
266         getCommWithOtherDeviceBtnn: function ui_getCommWithOtherDeviceBtnn() {
267             var communicateWithOtherDeviceButton;
268             communicateWithOtherDeviceButton = 
269                 $(this.getButtonHtml('Communicate with another device'));
270             communicateWithOtherDeviceButton
271                 .on('click', this.commWithOtherDevice);
272             return communicateWithOtherDeviceButton;
273         },
274
275         loadStartContent: function ui_loadStartContent() {
276             var startBox, contentStart, gap, comment;
277             contentStart = $('#content-start');
278             startBox = $('<div class="box" id="startBox"></div>');
279             gap = $('<div class="gap"></div>');
280             comment = $(this.getCommentHtml(localStorage));
281
282             contentStart.empty();
283             startBox
284                 .append(this.getChangeContactButton())
285                 .append(gap.clone())
286                 .append(this.getReadFromCardButton())
287                 .append(gap.clone())
288                 .append(this.getWriteToCardButton())
289                 .append(gap.clone())
290                 .append(this.getCommWithOtherDeviceBtnn())
291                 .prepend(comment);
292
293             contentStart.append(startBox);
294             contentStart.trigger('create');
295         },
296
297         loadStartPage: function ui_loadStartPage() {
298             if (localStorage.started === undefined) {
299                 this.loadTemporaryContent();
300             } else {
301                 this.loadStartContent();
302             }
303         },
304
305         /**
306          *
307          * @param {string} value
308          * @param {string} label
309          * @returns {string}
310          */
311         getLiHtml: function ui_getLiHtml(value, label) {
312             var html;
313             html = '<li class="ui-li-multiline" id="' + label + '">'
314                 + '<a href="#">' + '<span>' + label + '</span>'
315                 + '<span class="ui-li-text-sub">' + ((!value) ? '...' : value)
316                 + '</span>' + '</a>' + '</li>';
317             return html;
318         },
319
320         /**
321          *
322          * @param {string} phone
323          * @param {string} first
324          * @param {string} last
325          * @returns {string}
326          */
327         getContactsUlHtml: function ui_getContactsUlHtml(
328             phone,
329             phone_type,
330             first,
331             middle,
332             last,
333             vCard
334         ) {
335             var html;
336             html = '<ul data-role="listview" id="contacts-data">';
337             html += this.getLiHtml(first, 'First Name');
338             html += this.getLiHtml(middle, 'Middle Name');
339             html += this.getLiHtml(last, 'Last Name');
340             html += this.getLiHtml(phone, 'Phone');
341             html += this.getLiHtml(phone_type, 'Type');
342             html += this.getLiHtml(vCard, 'vCard');
343             html += '</ul>';
344             return html;
345         },
346
347         /**
348          * @param {object} contact
349          * @returns {string}
350          */
351         getContactsListElement: function ui_getContactsListElement(contact) {
352             var caller = $('<span class="ui-li-text-sub">')
353                     .text(contact.caller).html(),
354                 phoneNumber = contact.phoneNumber,
355                 html = '<li class="ui-li-multiline">'
356                     + '<a href="#">' + caller + '<span class="ui-li-text-sub">'
357                     + phoneNumber + '</span>' + '</a>' + '</li>';
358             return html;
359         },
360
361         prepareContactsTemplate: function ui_prepareContactsTemplate(
362             phone,
363             phone_type,
364             first,
365             middle,
366             last,
367             vCard
368         ) {
369             $('#content-contact > .ui-scrollview-view')
370                 .empty()
371                 .append(
372                     this.getContactsUlHtml(
373                         phone,
374                         phone_type,
375                         first,
376                         middle,
377                         last,
378                         vCard
379                     )
380                 );
381             $('#content-contact').trigger('create');
382         },
383
384         contactsCompare: function ui_contactsCompare(a, b) {
385             if (a.caller < b.caller) {
386                 return -1;
387             }
388             if (a.caller > b.caller) {
389                 return 1;
390             }
391             return 0;
392         },
393
394         createSortedContactArray: function ui_createSortedContactArray(
395             contacts
396         ) {
397             var i, len, sortedContactList = [],
398                 contact, phoneNumber;
399
400             for (i = 0, len = contacts.length; i < len; i += 1) {
401                 contact = contacts[i];
402                 if (contact.phoneNumbers.length === 0) {
403                     phoneNumber = '';
404                 } else {
405                     phoneNumber = contact.phoneNumbers[0].number;
406                 }
407                 sortedContactList.push({
408                     caller: this.prepareCallerName(contact),
409                     firstName: contact.name.firstName || '',
410                     middleName: contact.name.middleName || '',
411                     lastName: contact.name.lastName || '',
412                     phoneNumber: phoneNumber,
413                     id: contact.id,
414                     vCard: contact.convertToString('VCARD_30'),
415                     contact: contact
416                 });
417             }
418             sortedContactList.sort(this.contactsSort);
419
420             return sortedContactList;
421         },
422
423         createSortedContactList: function ui_createSortedContactList(
424             contacts
425         ) {
426             var sortedContactList = this.createSortedContactArray(contacts),
427                 ul = $('<ul data-role="listview" id="list-choose"></ul>'),
428                 i,
429                 len,
430                 listElement,
431                 listElementTap,
432                 self = this,
433                 contact;
434
435             listElementTap = function (event) {
436                 event.preventDefault();
437                 $(this).addClass('selected').siblings().removeClass('selected');
438                 self.app.saveDefaultCard();
439             };
440
441             for (i = 0, len = sortedContactList.length; i < len; i += 1) {
442                 contact = sortedContactList[i];
443                 if (contact.phoneNumber !== '') {
444                     listElement = $(this.getContactsListElement(contact));
445                     listElement
446                         .data('caller', contact.caller)
447                         .data('firstName', contact.firstName)
448                         .data('middleName', contact.middleName)
449                         .data('lastName', contact.lastName)
450                         .data('phoneNumber', contact.phoneNumber)
451                         .data('id', contact.id)
452                         .data('vCard', contact.vCard);
453                     if (localStorage.id === listElement.data('id')) {
454                         listElement.addClass('selected');
455                     }
456                     ul.append(listElement);
457                 }
458             }
459             ul.on('tap taphold click', 'li', listElementTap);
460             return ul;
461         },
462
463         showContactsList: function ui_showContactsList(contacts) {
464             var ul = this.createSortedContactList(contacts);
465             $('#content-choose > .ui-scrollview-view').empty().append(ul);
466             $('#content-choose').trigger('create');
467         },
468
469         moveToStartPage: function ui_moveToStartPage(monit) {
470             $('#start').data('monit', monit || '');
471             $.mobile.changePage('#start');
472         },
473
474         isActivePage: function ui_isActivePage(id) {
475             return (id === $.mobile.activePage.attr('id'));
476         },
477
478         refreshIfActivePage: function ui_refreshIfActivePage(id) {
479             if (this.isActivePage(id)) {
480                 $.mobile.activePage
481                     .trigger('pagebeforeshow')
482                     .trigger('pageshow');
483             }
484         },
485
486         moveToContactPage: function ui_moveToContactPage(obj) {
487             $('#start').data('monit', '');
488             $('#contact').data('contactsData', obj);
489             $.mobile.changePage('#contact');
490         },
491
492         defineEvents: function ui_defineEvents() {
493             var self = this;
494
495             $('#header-start .ui-btn-back').on('click', function (event) {
496                 event.preventDefault();
497                 self.app.nfc.stopNFC();
498             });
499
500             $('#header-start')
501                 .on('click', '.ui-btn-back.ui-focus', function () {
502                     return false;
503                 });
504
505             $('#footer-contact').on('click', '.ui-btn-back', function (event) {
506                 event.preventDefault();
507                 $.mobile.changePage('#start');
508             });
509
510             $('#footer-choose').on('click', '.ui-btn-back', function (event) {
511                 event.preventDefault();
512                 $.mobile.changePage('#start');
513             });
514
515             $('#choose').on('pageshow', function (event) {
516                 self.app.loadContacts(
517                     self.showContactsList.bind(self),
518                     function (e) {
519                         alert('Cannot load the contacts list: ' + e.message);
520                         console.error(e.message, e);
521                     }
522                 );
523             });
524
525             $('#contact').on('pageshow', function (event) {
526                 var data = $(this).data('contactsData');
527                 self.prepareContactsTemplate(
528                     data.phone,
529                     data.phone_type,
530                     data.first,
531                     data.middle,
532                     data.last,
533                     data.vCard
534                 );
535             });
536
537             $('#save-contact').on('click', function (event) {
538                 event.preventDefault();
539                 self.app.saveContact();
540             });
541
542             $('#start').on('pagebeforeshow', function () {
543                 if (self.app.started) {
544                     self.loadStartPage();
545                 }
546             });
547
548             $('#start').on('pageshow', function () {
549                 var obj = $(this),
550                     monit = obj.data('monit');
551                 if (monit !== '' && monit !== undefined) {
552                     self.showPopup(obj.data('monit'));
553                     obj.data('monit', '');
554                 }
555             });
556
557             $('#contact-nfc-error').bind({
558                 popupafterclose: function () {
559                     tizen.application.getCurrentApplication().exit();
560                 }
561             });
562
563             window.addEventListener('tizenhwkey', function (e) {
564                 if (e.keyName === 'back') {
565                     if ($.mobile.popup.active) {
566                         $.mobile.popup.active.close();
567                     } else if ($.mobile.activePage.attr('id') === 'start') {
568                         tizen.application.getCurrentApplication().exit();
569                     } else {
570                         self.app.nfc.timeExpired();
571                     }
572                 }
573             });
574
575             document.addEventListener('webkitvisibilitychange', function () {
576                 if (document.webkitVisibilityState === 'visible') {
577                     if ($.mobile.activePage.attr('id') === 'choose') {
578                         $.mobile.activePage.trigger('pageshow');
579                     }
580                     app.counterState = true;
581                 } else {
582                     app.counterState = false;
583                 }
584             });
585
586             $('#transfer').on('pageshow', function () {
587                 if (tizen.nfc.getDefaultAdapter().powered) {
588                     try {
589                         var option = $(this).data('option');
590                         if (option === 'read') {
591                             self.prepareWaitingPage(
592                                 'Card to device',
593                                 'PUT WIRELESS TAG<br>CLOSE TO<br>YOUR DEVICE'
594                             );
595                             self.app.nfc.card.setTagDetectRead();
596                         } else if (option === 'write') {
597                             self.prepareWaitingPage(
598                                 'Device to card',
599                                 'PUT WIRELESS TAG<br>CLOSE TO<br>YOUR DEVICE'
600                             );
601                             self.app.nfc.card.setTagDetectWrite();
602                         } else {
603                             self.prepareWaitingPage('Device to device',
604                                 'PUT YOUR DEVICE<br>CLOSE TO<br>OTHER DEVICE');
605                             self.app.nfc.peer.setTargetDetect();
606                         }
607                     } catch (e) {
608                         console.error(e.message);
609                     }
610                 } else {
611                     $.mobile.changePage('#start');
612                     alert('Please turn on NFC adapter');
613                 }
614             });
615         }
616
617     };
618
619 }());