diff --git a/clientapp/helpers/callbar.js b/clientapp/helpers/callbar.js deleted file mode 100644 index c258c84..0000000 --- a/clientapp/helpers/callbar.js +++ /dev/null @@ -1,248 +0,0 @@ -var CallBar = function (options) { - var spec = options || {}; - this.states = { - incoming: { - buttons: [ - { - cls: 'answer', - label: 'Answer' - }, - { - cls: 'ignore', - label: 'Ignore' - } - ] - }, - calling: { - buttons: [{ - cls: 'cancel', - label: 'Cancel' - }] - }, - active: { - buttons: [{ - cls: 'end', - label: 'End Call' - }], - timer: true - }, - inactive: { - buttons: [], - clearUser: true, - hidden: true - }, - ending: { - buttons: [] - }, - waiting: { - buttons: [] - } - }; - - this.config = { - defaultName: '', - defaultNumber: 'Unknown Number' - }; -}; - -CallBar.prototype.render = function () { - if (!this.dom) { - this.dom = this.domify(template(this)); - this.addButtonHandlers(); - document.body.insertBefore(this.dom, document.body.firstChild); - } else { - this.dom.innerHTML = this.domify(template(this)).innerHTML; - } - this.setState('inactive'); - return this.dom; -}; - -CallBar.prototype.addButtonHandlers = function () { - var self = this; - this.dom.addEventListener('click', function (e) { - var target = e.target; - if (target.tagName === 'BUTTON') { - if (self[target.className]) { - self[target.className](); - } - return false; - } - }, true); -}; - -CallBar.prototype.getStates = function () { - return Object.keys(this.states); -}; - -CallBar.prototype.setState = function (state) { - if (!this.dom) return this; - var buttons = this.dom.querySelectorAll('button'), - callActionsEl = this.dom.querySelector('.callActions'), - self = this, - stateDef = this.states[state], - forEach = Array.prototype.forEach; - if (stateDef) { - // set proper class on bar itself - this.getStates().forEach(function (cls) { - self.dom.classList.remove(cls); - }); - self.dom.classList.add(state); - - // set/remove 'hidden' class on bar itself - if (stateDef.hidden) { - self.dom.classList.remove('visible'); - document.body.classList.remove('candybarVisible'); - } else { - self.dom.classList.add('visible'); - document.body.classList.add('candybarVisible'); - } - - // remove all the buttons - forEach.call(buttons, function (button) { - button.parentElement.removeChild(button); - }); - - // add buttons - stateDef.buttons.forEach(function (button) { - callActionsEl.appendChild(self.domify('')); - }); - - // start/stop timer - if (stateDef.timer) { - if (this.timerStopped) { - this.startTimer(); - } - } else { - this.resetTimer(); - } - - // reset user if relevant - if (stateDef.clearUser) { - this.clearUser(); - } - - } else { - throw new Error('Invalid value for CallBar state. Valid values are: ' + this.getStates().join(', ')); - } - return this; -}; - -CallBar.prototype.endGently = function (delay) { - var self = this; - this.setState('ending'); - setTimeout(function () { - self.dom.classList.remove('visible'); - setTimeout(function () { - self.setState('inactive'); - self.clearUser(); - }, 1000); - }, 1000); - return this; -}; - -CallBar.prototype.setImageUrl = function (url) { - this.attachImageDom(!!url); - this.imageDom.src = url; - this.dom.classList[!!url ? 'add' : 'remove']('havatar'); -}; - -CallBar.prototype.attachImageDom = function (bool) { - if (!this.imageDom) { - this.imageDom = this.dom.querySelector('.callerAvatar'); - } - if (bool && !this.imageDom.parentElement) { - this.dom.insertBefore(this.imageDom, this.dom.firstChild); - } else if (this.imageDom.parentElement) { - this.imageDom.parentElement.removeChild(this.imageDom); - } - return this.imageDom; -}; - -CallBar.prototype.getUser = function () { - var user = this.user || {}, - self = this; - return { - picUrl: user.picUrl, - name: (user.name && user.name) || this.config.defaultName, - number: function () { - if (user.number && user.number !== self.config.defaultNumber) { - if (phoney) { - return phoney.stringify(user.number); - } else { - return escape(user.number); - } - } else { - return self.config.defaultNumber; - } - }() - }; -}; - -CallBar.prototype.setUser = function (details) { - this.user = details; - if (!this.dom) return; - var user = this.getUser(); - this.dom.querySelector('.callerNumber').innerHTML = user.number; - this.dom.querySelector('.callerName').innerHTML = user.name; - this.setImageUrl(user.picUrl); - return this; -}; - -CallBar.prototype.clearUser = function () { - this.setUser({ - picUrl: '', - name: '', - number: '' - }); - return this; -}; - -CallBar.prototype.domify = function (str) { - var div = document.createElement('div'); - div.innerHTML = str; - return div.firstElementChild; -}; - -CallBar.prototype.startTimer = function () { - this.timerStartTime = Date.now(); - this.timerStopped = false; - this.updateTimer(); - return this; -}; - -CallBar.prototype.stopTimer = function () { - this.timerStopped = true; - return this; -}; - -CallBar.prototype.resetTimer = function () { - this.timerStopped = true; - this.setTimeInDom('0:00:00'); - return this; -}; - -CallBar.prototype.updateTimer = function () { - if (this.timerStopped) return; - - var diff = Date.now() - this.timerStartTime, - s = Math.floor(diff / 1000) % 60, - min = Math.floor((diff / 1000) / 60) % 60, - hr = Math.floor(((diff / 1000) / 60) / 60) % 60, - time = [hr, this.zeroPad(min), this.zeroPad(s)].join(':'); - - if (this.time !== time) { - this.time = time; - this.setTimeInDom(time); - } - - setTimeout(this.updateTimer.bind(this), 100); -}; - -CallBar.prototype.setTimeInDom = function (timeString) { - if (!this.dom) return; - this.dom.querySelector('.callTime').innerHTML = timeString; -}; - -CallBar.prototype.zeroPad = function (num) { - return ((num + '').length === 1) ? '0' + num : num; -}; diff --git a/clientapp/models/call.js b/clientapp/models/call.js index c0ba7f1..0b873bd 100644 --- a/clientapp/models/call.js +++ b/clientapp/models/call.js @@ -9,7 +9,7 @@ var logger = require('andlog'); module.exports = HumanModel.define({ type: 'call', session: { - contactJid: 'object', + contact: 'object', jingleSession: 'object', state: ['string', true, 'inactive'], multiUser: ['boolean', true, false] diff --git a/clientapp/models/me.js b/clientapp/models/me.js index 633804f..36443b5 100644 --- a/clientapp/models/me.js +++ b/clientapp/models/me.js @@ -16,7 +16,7 @@ module.exports = HumanModel.define({ this.bind('change:hasFocus', function () { this.setActiveContact(this._activeContact); }, this); - + this.calls.bind('add remove reset', this.updateActiveCalls, this); this.contacts.bind('change:unreadCount', this.updateUnreadCount, this); app.state.bind('change:active', this.updateIdlePresence, this); }, @@ -124,5 +124,8 @@ module.exports = HumanModel.define({ count = ''; } app.state.badge = '' + count; + }, + updateActiveCalls: function () { + app.state.hasActiveCall = !!this.calls.length; } }); diff --git a/clientapp/models/state.js b/clientapp/models/state.js index 5b423e4..1c9645a 100644 --- a/clientapp/models/state.js +++ b/clientapp/models/state.js @@ -34,7 +34,8 @@ module.exports = HumanModel.define({ idleSince: 'date', allowAlerts: ['bool', true, false], badge: ['string', true, ''], - pageTitle: ['string', true, ''] + pageTitle: ['string', true, ''], + hasActiveCall: ['boolean', true, false] }, derived: { title: { diff --git a/clientapp/templates.js b/clientapp/templates.js index dd4c7c2..c0c8570 100644 --- a/clientapp/templates.js +++ b/clientapp/templates.js @@ -13,7 +13,7 @@ exports.pages = {}; exports.body = function anonymous(locals) { var buf = []; with (locals || {}) { - buf.push('
'); + buf.push('
'); } return buf.join(""); }; @@ -46,7 +46,7 @@ exports.includes.bareMessage = function anonymous(locals) { exports.includes.call = function anonymous(locals) { var buf = []; with (locals || {}) { - buf.push('

'); + buf.push('

'); } return buf.join(""); }; diff --git a/clientapp/templates/body.jade b/clientapp/templates/body.jade index c59d6f7..037d590 100644 --- a/clientapp/templates/body.jade +++ b/clientapp/templates/body.jade @@ -6,21 +6,22 @@ body strong disconnected button.reconnect Reconnect header#calls - aside#menu - nav.main + #wrapper + aside#menu + nav.main li - a(href="/logout", class="button") Logout + a(href="/logout", class="button") Logout li - a(href="/", class="button") - svg(version='1.1', xmlns='http://www.w3.org/2000/svg', xmlns:xlink='http://www.w3.org/1999/xlink', viewbox="0 0 25 25", height="25", width="25") - g(transform='scale(0.4)') - path(d='M37.418,34.3c-2.1-2.721-2.622-6.352-1.292-9.604c0.452-1.107,1.104-2.1,1.902-2.951 c-0.753-0.877-1.573-1.697-2.507-2.387l-2.609,1.408c-1.05-0.629-2.194-1.112-3.414-1.421l-0.845-2.833 c-0.75-0.112-1.512-0.188-2.287-0.188c-0.783,0-1.54,0.075-2.288,0.188l-0.851,2.833c-1.215,0.309-2.355,0.792-3.41,1.421 l-2.614-1.408c-1.229,0.912-2.318,2-3.228,3.231l1.404,2.612c-0.628,1.053-1.11,2.193-1.419,3.411l-2.832,0.849 c-0.114,0.75-0.187,1.508-0.187,2.287c0,0.778,0.073,1.537,0.187,2.286l2.832,0.848c0.309,1.22,0.791,2.36,1.419,3.413l-1.404,2.61 c0.909,1.231,1.999,2.321,3.228,3.231l2.614-1.406c1.055,0.628,2.195,1.11,3.41,1.42l0.851,2.832 c0.748,0.114,1.505,0.188,2.288,0.188c0.775,0,1.537-0.074,2.287-0.188l0.845-2.832c1.224-0.31,2.364-0.792,3.414-1.42l0.062,0.033 l2.045-3.02L37.418,34.3z M26.367,36.776c-2.777,0-5.027-2.253-5.027-5.027c0-2.775,2.25-5.028,5.027-5.028 c2.774,0,5.024,2.253,5.024,5.028C31.391,34.523,29.141,36.776,26.367,36.776z') - path(d='M51.762,24.505l-1.125-0.459l-1.451,3.55c-0.814,1.993-2.832,3.054-4.505,2.37l-0.355-0.144 c-1.673-0.686-2.37-2.856-1.558-4.849l1.451-3.551l-1.125-0.46c-2.225,0.608-4.153,2.2-5.092,4.501 c-1.225,2.997-0.422,6.312,1.771,8.436l-2.958,6.812l-2.204,3.249l-0.007,2.281l5.275,2.154l1.593-1.633l0.7-3.861l2.901-6.836 c3.049,0.018,5.947-1.785,7.174-4.779C53.186,28.983,52.924,26.499,51.762,24.505z') - | Settings - section#roster + a(href="/", class="button") + svg(version='1.1', xmlns='http://www.w3.org/2000/svg', xmlns:xlink='http://www.w3.org/1999/xlink', viewbox="0 0 25 25", height="25", width="25") + g(transform='scale(0.4)') + path(d='M37.418,34.3c-2.1-2.721-2.622-6.352-1.292-9.604c0.452-1.107,1.104-2.1,1.902-2.951 c-0.753-0.877-1.573-1.697-2.507-2.387l-2.609,1.408c-1.05-0.629-2.194-1.112-3.414-1.421l-0.845-2.833 c-0.75-0.112-1.512-0.188-2.287-0.188c-0.783,0-1.54,0.075-2.288,0.188l-0.851,2.833c-1.215,0.309-2.355,0.792-3.41,1.421 l-2.614-1.408c-1.229,0.912-2.318,2-3.228,3.231l1.404,2.612c-0.628,1.053-1.11,2.193-1.419,3.411l-2.832,0.849 c-0.114,0.75-0.187,1.508-0.187,2.287c0,0.778,0.073,1.537,0.187,2.286l2.832,0.848c0.309,1.22,0.791,2.36,1.419,3.413l-1.404,2.61 c0.909,1.231,1.999,2.321,3.228,3.231l2.614-1.406c1.055,0.628,2.195,1.11,3.41,1.42l0.851,2.832 c0.748,0.114,1.505,0.188,2.288,0.188c0.775,0,1.537-0.074,2.287-0.188l0.845-2.832c1.224-0.31,2.364-0.792,3.414-1.42l0.062,0.033 l2.045-3.02L37.418,34.3z M26.367,36.776c-2.777,0-5.027-2.253-5.027-5.027c0-2.775,2.25-5.028,5.027-5.028 c2.774,0,5.024,2.253,5.024,5.028C31.391,34.523,29.141,36.776,26.367,36.776z') + path(d='M51.762,24.505l-1.125-0.459l-1.451,3.55c-0.814,1.993-2.832,3.054-4.505,2.37l-0.355-0.144 c-1.673-0.686-2.37-2.856-1.558-4.849l1.451-3.551l-1.125-0.46c-2.225,0.608-4.153,2.2-5.092,4.501 c-1.225,2.997-0.422,6.312,1.771,8.436l-2.958,6.812l-2.204,3.249l-0.007,2.281l5.275,2.154l1.593-1.633l0.7-3.861l2.901-6.836 c3.049,0.018,5.947-1.785,7.174-4.779C53.186,28.983,52.924,26.499,51.762,24.505z') + | Settings + section#roster h1 Roster nav - section#bookmarks + section#bookmarks h1 Bookmarks nav - section#pages + main#pages diff --git a/clientapp/templates/includes/call.jade b/clientapp/templates/includes/call.jade index 2d4ce7e..94a0da1 100644 --- a/clientapp/templates/includes/call.jade +++ b/clientapp/templates/includes/call.jade @@ -5,3 +5,8 @@ span.callerNumber h2.callTime .callActions + button.answer Answer + button.ignore Ignore + button.cancel Cancel + button.end End + button.mute Mute diff --git a/clientapp/views/main.js b/clientapp/views/main.js index aa1ba06..4adbe58 100644 --- a/clientapp/views/main.js +++ b/clientapp/views/main.js @@ -19,12 +19,14 @@ module.exports = HumanView.extend({ 'click .reconnect': 'handleReconnect' }, classBindings: { - connected: '#connectionOverlay' + connected: '#connectionOverlay', + hasActiveCall: '#wrapper' }, render: function () { $('head').append(templates.head()); $('body').removeClass('aux'); this.renderAndBind(); + console.log('this.model', this.model); this.renderCollection(me.contacts, ContactListItem, this.$('#roster nav')); this.renderCollection(me.mucs, MUCListItem, this.$('#bookmarks nav')); this.renderCollection(me.calls, CallView, this.$('#calls')); diff --git a/public/css/_mixins.styl b/public/css/_mixins.styl index ff556c9..0afb0b6 100644 --- a/public/css/_mixins.styl +++ b/public/css/_mixins.styl @@ -36,17 +36,17 @@ turn($deg) -o-transform: rotate($deg) transform: rotate($deg) -transform($param) - -webkit-transform: $param - -moz-transform: $param - -ms-transform: $param - transform: $param +transform() + -webkit-transform: arguments + -moz-transform: arguments + -ms-transform: arguments + transform: arguments -transition($attr, $dur, $timing, $delay) - -webkit-transition: $attr $dur $timing $delay - -o-transition: $attr $dur $timing $delay - transition: $attr $dur $timing $delay - -moz-transition: $attr $dur $timing $delay +transition() + -webkit-transition: arguments + -o-transition: arguments + transition: arguments + -moz-transition: arguments flip-horizontal() -moz-transform: scaleX(-1) diff --git a/public/css/app/callbar.styl b/public/css/app/callbar.styl index 30bc81c..164fe8f 100644 --- a/public/css/app/callbar.styl +++ b/public/css/app/callbar.styl @@ -1,77 +1,77 @@ @import _mixins @import _variables -body - position: relative !important - -webkit-transition: top 1s +$callHeight = 80px - &.candybarVisible - top: 100px +#wrapper + position: relative !important + transition: all 1s + + &.hasActiveCall + transform: translateY($callHeight) #calls position: fixed - top: -120px + top: 0 left: 0px - -webkit-transition: background-color 1s - -webkit-transition: top 1s + transition: all 1s width: 100% - height: 80px - padding: 10px + height: $callHeight z-index: 1000 + background: white - &.visible - top: 0px + &:empty, &.ending + transform: translateY(-($callHeight)) - &.havatar + .call + height: $callHeight + padding: 0 + margin: 0 + + &.incoming + background: $activeBlue + .callTime + display: none + .callerName:before + content: "Incoming: " + + &.waiting + background: $activeBlue + + .spinner div + background-color: #fff + + &.calling + callbar($blue) + .callTime + display: none + .callerName:before + content: "Calling: " + + &.active + callbar($green) + .callerName:before + content: "On Call: " + + &.inactive + callbar(#fff) + + &.remote + callbar($blue #333) + .callTime + display: none + + &.ending + .callerName:before + content: "Call ending with: " + callbar($grey) + .callActions - left: 100px - .caller - margin-left: 90px - - &.incoming - background: blue - .callTime - display: none - .callerName:before - content: "Incoming: " - - &.waiting - callbar($orange) - - .spinner div - background-color: #fff - - &.calling - callbar($blue) - .callTime - display: none - .callerName:before - content: "Calling: " - - &.active - callbar($green) - .callerName:before - content: "On Call: " - - &.inactive - callbar(#fff) - - &.remote - callbar($blue #333) - .callTime - display: none - - &.ending - .callerName:before - content: "Call ending with: " - callbar($grey) - - .callActions - position: absolute - left: 10px - top: 50px - display: block - width: 100% + position: absolute + left: 10px + top: 50px + display: block + width: 100% nav float: left @@ -104,22 +104,19 @@ body .callerAvatar float: left - width: 65px - height: 65px - border: 5px solid #eee + width: 50px + height: 50px margin-right: 10px - - .callerName, .callTime + roundall(25px) + + .callerName, .callTime font-weight: bold color: #fff text_shadow(rgba(0,0,0,.7),0,1px,0) line-height: 1 .caller - margin: - top: 0px - right: 30px - left: 0px + margin: 0 font-size: 20px padding-bottom: 0px border-bottom: 2px groove rgba(255,255,255,.4) diff --git a/public/css/otalk.css b/public/css/otalk.css index 5506da4..bd2b9d0 100644 --- a/public/css/otalk.css +++ b/public/css/otalk.css @@ -1027,61 +1027,75 @@ button:hover, a.button:hover { background: #007aa7; } -body { +#wrapper { position: relative !important; - -webkit-transition: top 1s; + -webkit-transition: all 1s; + -o-transition: all 1s; + transition: all 1s; + -moz-transition: all 1s; } -body.candybarVisible { - top: 100px; +#wrapper.hasActiveCall { + -webkit-transform: translateY(80px); + -moz-transform: translateY(80px); + -ms-transform: translateY(80px); + transform: translateY(80px); } #calls { position: fixed; - top: -120px; + top: 0; left: 0px; - -webkit-transition: background-color 1s; - -webkit-transition: top 1s; + -webkit-transition: all 1s; + -o-transition: all 1s; + transition: all 1s; + -moz-transition: all 1s; width: 100%; height: 80px; - padding: 10px; z-index: 1000; + background: #fff; } -#calls.visible { - top: 0px; +#calls:empty, +#calls.ending { + -webkit-transform: translateY(-80px); + -moz-transform: translateY(-80px); + -ms-transform: translateY(-80px); + transform: translateY(-80px); } -#calls.havatar .callActions { - left: 100px; +#calls .call { + height: 80px; + padding: 0; + margin: 0; } -#calls.havatar .caller { - margin-left: 90px; +#calls .call.incoming { + background: #00aeef; } -#calls.incoming { - background: #00f; -} -#calls.incoming .callTime { +#calls .call.incoming .callTime { display: none; } -#calls.incoming .callerName:before { +#calls .call.incoming .callerName:before { content: "Incoming: "; } -#calls.waiting .spinner div { +#calls .call.waiting { + background: #00aeef; +} +#calls .call.waiting .spinner div { background-color: #fff; } -#calls.calling .callTime { +#calls .call.calling .callTime { display: none; } -#calls.calling .callerName:before { +#calls .call.calling .callerName:before { content: "Calling: "; } -#calls.active .callerName:before { +#calls .call.active .callerName:before { content: "On Call: "; } -#calls.remote .callTime { +#calls .call.remote .callTime { display: none; } -#calls.ending .callerName:before { +#calls .call.ending .callerName:before { content: "Call ending with: "; } -#calls .callActions { +#calls .call .callActions { position: absolute; left: 10px; top: 50px; @@ -1127,10 +1141,15 @@ rgba(0,0,0,0.2) } #calls .callerAvatar { float: left; - width: 65px; - height: 65px; - border: 5px solid #eee; + width: 50px; + height: 50px; margin-right: 10px; + -moz-border-radius: 25px; + -webkit-border-radius: 25px; + -khtml-border-radius: 25px; + -o-border-radius: 25px; + -border-radius: 25px; + border-radius: 25px; } #calls .callerName, #calls .callTime { @@ -1140,14 +1159,11 @@ rgba(0,0,0,0.7) line-height: 1; } #calls .caller { + margin: 0; font-size: 20px; padding-bottom: 0px; border-bottom: 2px groove rgba(255,255,255,0.4); } -#calls .caller margin:top: 0px { - right: 30px; - left: 0px; -} #calls .callerName { display: inline; } diff --git a/public/x-manifest.cache b/public/x-manifest.cache index d540405..6ba0198 100644 --- a/public/x-manifest.cache +++ b/public/x-manifest.cache @@ -1,5 +1,5 @@ CACHE MANIFEST -# 0.0.1 1381864472792 +# 0.0.1 1381879209705 CACHE: /app.js