/* globals CallsHandler, FontSizeManager, KeypadManager, LockScreenSlide, MozActivity, SettingsListener, Utils, mozIntl */ /* jshint nonew: false */ 'use strict'; var CallScreen = { _ticker: null, _screenWakeLock: null, _typedNumber: '', callEndPromptTime: 2000, body: document.body, screen: document.getElementById('call-screen'), lockscreenConnStates: document.getElementById('lockscreen-conn-states'), views: document.getElementById('views'), calls: document.getElementById('calls'), mainContainer: document.getElementById('main-container'), contactBackground: document.getElementById('contact-background'), callOptions: document.getElementById('call-options'), callToolbar: document.getElementById('co-advanced'), muteButton: document.getElementById('mute'), speakerButton: document.getElementById('speaker'), bluetoothButton: document.getElementById('bt'), keypadButton: document.getElementById('keypad-visibility'), placeNewCallButton: document.getElementById('place-new-call'), holdButton: document.getElementById('on-hold'), mergeButton: document.getElementById('merge'), holdAndMergeContainer: document.getElementById('hold-and-merge-container'), hideBarMuteButton: document.getElementById('keypad-hidebar-mute-action'), bluetoothMenu: document.getElementById('bluetooth-menu'), switchToDeviceButton: document.getElementById('btmenu-btdevice'), switchToReceiverButton: document.getElementById('btmenu-receiver'), switchToSpeakerButton: document.getElementById('btmenu-speaker'), bluetoothMenuCancel: document.getElementById('btmenu-cancel'), answerButton: document.getElementById('callbar-answer'), rejectButton: document.getElementById('callbar-hang-up'), incomingContainer: document.getElementById('incoming-container'), incomingInfo: document.getElementById('incoming-info'), incomingNumber: document.getElementById('incoming-number'), incomingSim: document.getElementById('incoming-sim'), incomingNumberAdditionalTel: document.getElementById('incoming-number-additional-info-tel'), incomingNumberAdditionalTelType: document.getElementById('incoming-number-additional-info-tel-type'), incomingAnswer: document.getElementById('incoming-answer'), incomingEnd: document.getElementById('incoming-end'), incomingIgnore: document.getElementById('incoming-ignore'), lockedClockTime: document.getElementById('lockscreen-clock-time'), lockedDate: document.getElementById('lockscreen-date'), statusMessage: document.getElementById('statusMsg'), showStatusMessage: function cs_showStatusMessage(message) { var STATUS_TIME = 2000; var paragraph = this.statusMessage.querySelector('p'); var self = this; if (typeof(message) === 'string') { navigator.mozL10n.setAttributes(paragraph, message); } else if (message.id) { navigator.mozL10n.setAttributes(paragraph, message.id, message.args); } this.statusMessage.classList.add('visible'); this.statusMessage.addEventListener('transitionend', function tend(evt) { evt.stopPropagation(); self.statusMessage.removeEventListener('transitionend', tend); setTimeout(function hide() { self.statusMessage.classList.remove('visible'); }, STATUS_TIME); }); }, updateCallsDisplay: function cs_updateCallsDisplay() { var visibleCalls = this.calls.querySelectorAll('section:not([hidden])').length; this.body.classList.toggle('single-line', visibleCalls <= 1); this.calls.classList.toggle('big-duration', visibleCalls <= 1); CallsHandler.updateAllPhoneNumberDisplays(); }, hidePlaceNewCallButton: function cs_hidePlaceNewCallButton() { this.callToolbar.classList.add('no-add-call'); }, showPlaceNewCallButton: function cs_showPlaceNewCallButton() { this.callToolbar.classList.remove('no-add-call'); }, /** * When enabled hides the end-and-answer button in call waiting mode and * displays only the hold-and-answer one. * * @param {Boolean} enabled Enables hold-and-answer-only operation. */ set holdAndAnswerOnly(enabled) { this.incomingContainer.classList.toggle('hold-and-answer-only', enabled); }, /** * When enabled displays the CDMA-specific call-waiting UI * * @param {Boolean} enabled Enables the CDMA call-waiting UI. */ set cdmaCallWaiting(enabled) { this.calls.classList.toggle('switch', enabled); this.callToolbar.classList.toggle('no-add-call', enabled); }, get inStatusBarMode() { return window.innerHeight <= 40; }, init: function cs_init() { this.muteButton.addEventListener('click', this.toggleMute.bind(this)); this.hideBarMuteButton.addEventListener('click', this.toggleMute.bind(this)); this.keypadButton.addEventListener('click', this.showKeypad.bind(this)); this.placeNewCallButton.addEventListener('click', this.placeNewCall.bind(this)); this.speakerButton.addEventListener('click', this.toggleSpeaker.bind(this)); this.bluetoothButton.addEventListener('click', this.toggleBluetoothMenu.bind(this)); this.holdButton.addEventListener('click', CallsHandler.holdOrResumeSingleCall.bind(this)); this.mergeButton.addEventListener('click', CallsHandler.mergeCalls.bind(this)); this.answerButton.addEventListener('click', CallsHandler.answer); this.rejectButton.addEventListener('click', CallsHandler.end); this.switchToDeviceButton.addEventListener( 'click', this.switchToDefaultOut.bind(this, false)); this.switchToReceiverButton.addEventListener( 'click', this.switchToReceiver.bind(this)); this.switchToSpeakerButton.addEventListener( 'click', this.switchToSpeaker.bind(this)); this.bluetoothMenuCancel.addEventListener( 'click', this.toggleBluetoothMenu.bind(this)); this.incomingAnswer.addEventListener('click', CallsHandler.holdAndAnswer); this.incomingEnd.addEventListener('click', CallsHandler.endAndAnswer); this.incomingIgnore.addEventListener('click', CallsHandler.ignore); this.calls.addEventListener('click', CallsHandler.toggleCalls.bind(this)); window.addEventListener('resize', this.resizeHandler.bind(this)); SettingsListener.observe('wallpaper.image', null, this._wallpaperImageHandler.bind(this)); // Interaction with the lockscreen this._lockScreenLayoutInitialized = false; navigator.mozSettings.addObserver( 'lockscreen.locked', this._lockscreenStateChange.bind(this) ); this.syncSpeakerEnabled(); }, initLockScreenConnInfoManager: function cs_initLockScreenConnInfoManager() { /* mobile connection state on lock screen */ if (window.navigator.mozMobileConnections) { new window.LockScreenConnInfoManager(CallScreen.lockscreenConnStates); } }, initLockScreenSlide: function cs_initLockScreenSlide() { // Setup incoming call screen slider this.hangUpIcon = document.getElementById('lockscreen-area-hangup'); this.pickUpIcon = document.getElementById('lockscreen-area-pickup'); this.initUnlockerEvents(); new LockScreenSlide({ useNewStyle: true, IDs: { overlay: 'main-container', areas: { left: 'lockscreen-area-hangup', right: 'lockscreen-area-pickup' }, }, trackNew: { strokeColorTop: 'rgba(0, 0, 0, 0)', strokeColorBottom: 'rgba(0, 0, 0, 0)', fillColorTop: 'rgba(0, 0, 0, 0.1)', fillColorBottom: 'rgba(0, 0, 0, 0.1)' }, colors: { left: { touchedColor: '224, 0, 0', touchedColorStop: '255, 255, 255' }, right: { touchedColor: '0, 173, 173', touchedColorStop: '255, 255, 255' } }, iconBG: { left: { color: 'rgba(224, 0, 0, 0.80)' }, right: { color: 'rgba(0, 173, 173, 0.80)' } }, resourcesNew: { larrow: '/style/images/lock_screen/lockscreen_toggle_arrow_left.png', rarrow: '/style/images/lock_screen/lockscreen_toggle_arrow_right.png' } }); }, _lockscreenStateChange: function cs_lockscreenStateChange(event) { if (event.settingValue) { if (this.screen.dataset.layout === 'incoming') { this.initLockScreenLayout(); this.render('incoming-locked'); } this.initUnlockerEvents(); } else { if (this.screen.dataset.layout === 'incoming-locked') { this.render('incoming'); } this.suspendUnlockerEvents(); } }, _wallpaperImageHandler: function cs_wallpaperImageHandler(image) { this.mainContainer.style.backgroundImage = 'url(' + (typeof image === 'string' ? image : URL.createObjectURL(image)) + ')'; }, setCallerContactImage: function cs_setCallerContactImage() { var activeCallForContactImage = CallsHandler.activeCallForContactImage; var blob = activeCallForContactImage && activeCallForContactImage.photo; var background = blob ? 'url(' + URL.createObjectURL(blob) + ')' : ''; this.contactBackground.style.backgroundImage = background; }, insertCall: function cs_insertCall(node) { this.calls.appendChild(node); this.updateCallsDisplay(); }, removeCall: function cs_removeCall(node) { if (node.parentNode) { node.parentNode.removeChild(node); this.updateCallsDisplay(); } }, resizeHandler: function cs_resizeHandler() { // If a user has the keypad opened, we want to display the number called // while in status bar mode. And restore the digits typed when exiting. if (!this.body.classList.contains('showKeypad')) { this.updateCallsDisplay(this.inStatusBarMode); } else if (this.inStatusBarMode) { this._typedNumber = KeypadManager._phoneNumber; KeypadManager.restorePhoneNumber(); } else { KeypadManager.updatePhoneNumber(this._typedNumber, 'begin', true); } }, _lockScreenLayoutInitialized: false, initLockScreenLayout: function cs_initLockScreenLayout() { this.showClock(new Date()); if (!this._lockScreenLayoutInitialized) { this.initLockScreenConnInfoManager(); this.initLockScreenSlide(); this._lockScreenLayoutInitialized = true; } }, toggleMute: function cs_toggleMute() { this.muteButton.classList.toggle('active-state'); this.hideBarMuteButton.classList.toggle('active-state'); this.calls.classList.toggle('muted'); CallsHandler.toggleMute(); }, unmute: function cs_unmute() { this.muteButton.classList.remove('active-state'); this.hideBarMuteButton.classList.remove('active-state'); this.calls.classList.remove('muted'); CallsHandler.unmute(); }, toggleSpeaker: function cs_toggleSpeaker() { this.speakerButton.classList.toggle('active-state'); CallsHandler.toggleSpeaker(); }, toggleBluetoothMenu: function cs_toggleBluetoothMenu(value) { if (typeof value != 'boolean') { this.bluetoothMenu.classList.toggle('display'); } else { this.bluetoothMenu.classList.toggle('display', value); } }, switchToSpeaker: function cs_switchToReceiver() { this.speakerButton.classList.add('active-state'); this.bluetoothButton.classList.add('active-state'); CallsHandler.switchToSpeaker(); this.toggleBluetoothMenu(false); }, switchToReceiver: function cs_switchToReceiver() { this.speakerButton.classList.remove('active-state'); this.bluetoothButton.classList.remove('active-state'); CallsHandler.switchToReceiver(); this.toggleBluetoothMenu(false); }, setShowIsHeld: function cs_setShowIsHeld(enabled) { this.holdButton.classList.toggle('active-state', enabled); }, // when BT device available: switch to BT // when BT device unavailable: switch to receiver switchToDefaultOut: function cs_switchToDefaultOut(doNotConnect) { this.speakerButton.classList.remove('active-state'); this.bluetoothButton.classList.add('active-state'); CallsHandler.switchToDefaultOut(doNotConnect); this.toggleBluetoothMenu(false); }, setBTReceiverIcon: function cs_setBTReceiverIcon(enabled) { if (enabled) { this.speakerButton.classList.add('hide'); this.bluetoothButton.classList.remove('hide'); } else { this.speakerButton.classList.remove('hide'); this.bluetoothButton.classList.add('hide'); } }, showKeypad: function cs_showKeypad() { KeypadManager.render('oncall'); this.body.classList.add('showKeypad'); }, hideKeypad: function cs_hideKeypad() { KeypadManager.restorePhoneNumber(); KeypadManager.restoreAdditionalContactInfo(); this.body.classList.remove('showKeypad'); }, placeNewCall: function cs_placeNewCall() { new MozActivity({ name: 'dial', data: { type: 'webtelephony/number', number: '' } }); }, render: function cs_render(layout_type) { this.screen.dataset.layout = layout_type; }, showClock: function cs_showClock(now) { var formatter = mozIntl.DateTimeFormat(navigator.languages, { hour12: navigator.mozHour12, dayperiod: false, hour: 'numeric', minute: 'numeric' }); var timeText = formatter.format(now); var dateText = now.toLocaleString(navigator.languages, { weekday: 'long', month: 'long', day: 'numeric' }); this.lockedClockTime.textContent = timeText; this.lockedDate.textContent = dateText; }, showIncoming: function cs_showIncoming() { this.body.classList.remove('showKeypad'); this.callOptions.classList.add('transparent'); this.incomingContainer.classList.add('displayed'); this._screenWakeLock = navigator.requestWakeLock('screen'); }, hideIncoming: function cs_hideIncoming() { this.callOptions.classList.remove('transparent'); this.incomingContainer.classList.remove('displayed'); if (this._screenWakeLock) { this._screenWakeLock.unlock(); this._screenWakeLock = null; } this.setCallerContactImage(); }, enableKeypadButton: function cs_enableKeypadButton() { this.keypadButton.removeAttribute('disabled'); }, disableKeypadButton: function cs_disableKeypadButton() { this.keypadButton.setAttribute('disabled', 'disabled'); }, syncSpeakerEnabled: function cs_syncSpeakerEnabled() { if (navigator.mozTelephony.speakerEnabled) { this.speakerButton.classList.add('active-state'); } else { this.speakerButton.classList.remove('active-state'); } }, enableMuteButton: function cs_enableMuteButton() { this.muteButton.removeAttribute('disabled'); }, disableMuteButton: function cs_disableMuteButton() { this.muteButton.setAttribute('disabled', 'disabled'); }, enablePlaceNewCallButton: function cs_enablePlaceNewCallButton() { this.placeNewCallButton.removeAttribute('disabled'); }, disablePlaceNewCallButton: function cs_disablePlaceNewCallButton() { this.placeNewCallButton.setAttribute('disabled', 'disabled'); }, enableSpeakerButton: function cs_enableSpeakerButton() { this.speakerButton.removeAttribute('disabled'); }, disableSpeakerButton: function cs_disableSpeakerButton() { this.speakerButton.setAttribute('disabled', 'disabled'); }, showOnHoldButton: function cs_showOnHoldButton() { this.holdButton.classList.remove('hide'); }, hideOnHoldButton: function cs_hideOnHoldButton() { this.holdButton.classList.add('hide'); }, enableOnHoldButton: function cs_enableOnHoldButton() { this.holdButton.removeAttribute('disabled'); }, disableOnHoldButton: function cs_disableOnHoldButton() { this.holdButton.setAttribute('disabled', 'disabled'); }, showMergeButton: function cs_showMergeButton() { this.mergeButton.classList.remove('hide'); }, hideMergeButton: function cs_hideMergeButton() { this.mergeButton.classList.add('hide'); }, showOnHoldAndMergeContainer: function cs_showOnHoldAndMergeContainer() { this.holdAndMergeContainer.style.display = 'block'; }, hideOnHoldAndMergeContainer: function cs_hideOnHoldAndMergeContainer() { this.holdAndMergeContainer.style.display = 'none'; }, createTicker: function(durationNode) { var durationChildNode = durationNode.querySelector('span'); if (durationNode.dataset.tickerId) { return false; } durationChildNode.removeAttribute('data-l10n-id'); durationChildNode.textContent = '00:00'; durationNode.classList.add('isTimer'); var ticker = setInterval(function ut_updateTimer(startTime) { // Bug 834334: Ensure that 28.999 -> 29.000 var delta = Math.round((Date.now() - startTime) / 1000) * 1000; Utils.prettyDuration(durationChildNode, delta); }, 1000, Date.now()); durationNode.dataset.tickerId = ticker; return true; }, stopTicker: function(durationNode) { durationNode.classList.remove('isTimer'); clearInterval(durationNode.dataset.tickerId); delete durationNode.dataset.tickerId; }, handleEvent: function cs_handleEvent(evt) { var state = null, statePrev = null; switch (evt.type) { case 'lockscreenslide-unlocker-initializer': break; case 'lockscreenslide-near-left': state = evt.detail.state; statePrev = evt.detail.statePrev; if (state === 'accelerating') { CallScreen.hangUpIcon.classList.add('triggered'); } else { CallScreen.hangUpIcon.classList.remove('triggered'); } break; case 'lockscreenslide-near-right': state = evt.detail.state; statePrev = evt.detail.statePrev; if (state === 'accelerating') { CallScreen.pickUpIcon.classList.add('triggered'); } else { CallScreen.pickUpIcon.classList.remove('triggered'); } break; case 'lockscreenslide-unlocking-start': break; case 'lockscreenslide-unlocking-stop': break; case 'lockscreenslide-activate-left': CallsHandler.end(); break; case 'lockscreenslide-activate-right': CallsHandler.answer(); break; } }, cdmaConferenceCall: function cs_cdmaConferenceCall() { this.hidePlaceNewCallButton(); this.calls.classList.add('cdma-conference-call'); }, initUnlockerEvents: function cs_initUnlockerEvents() { window.addEventListener('lockscreenslide-unlocker-initializer', this); window.addEventListener('lockscreenslide-near-left', this); window.addEventListener('lockscreenslide-near-right', this); window.addEventListener('lockscreenslide-unlocking-start', this); window.addEventListener('lockscreenslide-activate-left', this); window.addEventListener('lockscreenslide-activate-right', this); window.addEventListener('lockscreenslide-unlocking-stop', this); }, suspendUnlockerEvents: function cs_initUnlockerEvents() { window.removeEventListener('lockscreenslide-unlocker-initializer', this); window.removeEventListener('lockscreenslide-near-left', this); window.removeEventListener('lockscreenslide-near-right', this); window.removeEventListener('lockscreenslide-unlocking-start', this); window.removeEventListener('lockscreenslide-activate-left', this); window.removeEventListener('lockscreenslide-activate-right', this); window.removeEventListener('lockscreenslide-unlocking-stop', this); }, getScenario: function cs_getScenario() { var scenario; if (this.inStatusBarMode) { scenario = FontSizeManager.STATUS_BAR; } else if (this.body.classList.contains('single-line')) { scenario = FontSizeManager.SINGLE_CALL; } else { scenario = FontSizeManager.CALL_WAITING; } return scenario; } };