mirror of
https://github.com/moparisthebest/kaiwa
synced 2024-11-24 10:12:18 -05:00
starting to add active calls, collection and start of UI
This commit is contained in:
parent
4022b53a86
commit
ba9b0a7baf
248
clientapp/helpers/callbar.js
Normal file
248
clientapp/helpers/callbar.js
Normal file
@ -0,0 +1,248 @@
|
||||
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('<button class="' + button.cls + '">' + button.label + '</button>'));
|
||||
});
|
||||
|
||||
// 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;
|
||||
};
|
17
clientapp/models/call.js
Normal file
17
clientapp/models/call.js
Normal file
@ -0,0 +1,17 @@
|
||||
/*global app, me, client*/
|
||||
"use strict";
|
||||
|
||||
var _ = require('underscore');
|
||||
var HumanModel = require('human-model');
|
||||
var logger = require('andlog');
|
||||
|
||||
|
||||
module.exports = HumanModel.define({
|
||||
type: 'call',
|
||||
session: {
|
||||
contactJid: 'object',
|
||||
jingleSession: 'object',
|
||||
state: ['string', true, 'inactive'],
|
||||
multiUser: ['boolean', true, false]
|
||||
}
|
||||
});
|
10
clientapp/models/calls.js
Normal file
10
clientapp/models/calls.js
Normal file
@ -0,0 +1,10 @@
|
||||
"use strict";
|
||||
|
||||
var BaseCollection = require('./baseCollection');
|
||||
var Call = require('./call');
|
||||
|
||||
|
||||
module.exports = BaseCollection.extend({
|
||||
type: 'calls',
|
||||
model: Call
|
||||
});
|
@ -9,6 +9,7 @@ var HumanModel = require('human-model');
|
||||
var Resources = require('./resources');
|
||||
var Messages = require('./messages');
|
||||
var Message = require('./message');
|
||||
var logger = require('andlog');
|
||||
var fetchAvatar = require('../helpers/fetchAvatar');
|
||||
|
||||
|
||||
@ -46,6 +47,7 @@ module.exports = HumanModel.define({
|
||||
topResource: 'string',
|
||||
unreadCount: ['number', true, 0],
|
||||
_forceUpdate: ['number', true, 0],
|
||||
// options: incomingCall, ringing, activeCall, starting
|
||||
callState: ['string', true, ''],
|
||||
stream: 'object'
|
||||
},
|
||||
@ -153,7 +155,7 @@ module.exports = HumanModel.define({
|
||||
messages: Messages
|
||||
},
|
||||
call: function () {
|
||||
if (this.jingleResources) {
|
||||
if (this.jingleResources.length) {
|
||||
var peer = this.jingleResources[0];
|
||||
this.callState = 'starting';
|
||||
app.api.jingle.startLocalMedia(null, function (err) {
|
||||
@ -161,6 +163,8 @@ module.exports = HumanModel.define({
|
||||
app.api.call(peer.id);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
logger.error('no jingle resources for this user');
|
||||
}
|
||||
},
|
||||
setAvatar: function (id, type) {
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
var HumanModel = require('human-model');
|
||||
var Contacts = require('./contacts');
|
||||
var Calls = require('./calls');
|
||||
var Contact = require('./contact');
|
||||
var MUCs = require('./mucs');
|
||||
var MUC = require('./muc');
|
||||
@ -32,7 +33,8 @@ module.exports = HumanModel.define({
|
||||
},
|
||||
collections: {
|
||||
contacts: Contacts,
|
||||
mucs: MUCs
|
||||
mucs: MUCs,
|
||||
calls: Calls
|
||||
},
|
||||
setActiveContact: function (jid) {
|
||||
var prev = this.getContact(this._activeContact);
|
||||
|
@ -13,7 +13,7 @@ exports.pages = {};
|
||||
exports.body = function anonymous(locals) {
|
||||
var buf = [];
|
||||
with (locals || {}) {
|
||||
buf.push('<body><div id="connectionOverlay"><aside id="connectionStatus" class="box"><p> \nYou\'re currently <strong>disconnected</strong></p><button class="reconnect">Reconnect</button></aside></div><aside id="menu"><nav class="main"><li><a href="/logout" class="button">Logout</a></li><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><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"></path></g></svg>Settings</a></li></nav><section id="roster"><h1>Roster</h1><nav></nav></section><section id="bookmarks"><h1>Bookmarks</h1><nav></nav></section></aside><section id="pages"></section></body>');
|
||||
buf.push('<body><div id="connectionOverlay"><aside id="connectionStatus" class="box"><p> \nYou\'re currently <strong>disconnected</strong></p><button class="reconnect">Reconnect</button></aside></div><header id="calls"></header><aside id="menu"><nav class="main"><li><a href="/logout" class="button">Logout</a></li><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><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"></path></g></svg>Settings</a></li></nav><section id="roster"><h1>Roster</h1><nav></nav></section><section id="bookmarks"><h1>Bookmarks</h1><nav></nav></section></aside><section id="pages"></section></body>');
|
||||
}
|
||||
return buf.join("");
|
||||
};
|
||||
@ -42,6 +42,15 @@ exports.includes.bareMessage = function anonymous(locals) {
|
||||
return buf.join("");
|
||||
};
|
||||
|
||||
// call.jade compiled template
|
||||
exports.includes.call = function anonymous(locals) {
|
||||
var buf = [];
|
||||
with (locals || {}) {
|
||||
buf.push('<div class="call"><img class="callerAvatar"/><h1 class="caller"><span class="callerName"></span><span class="callerNumber"></span></h1><h2 class="callTime"></h2><div class="callActions"></div></div>');
|
||||
}
|
||||
return buf.join("");
|
||||
};
|
||||
|
||||
// contactListItem.jade compiled template
|
||||
exports.includes.contactListItem = function anonymous(locals) {
|
||||
var buf = [];
|
||||
@ -160,7 +169,7 @@ exports.misc.growlMessage = function anonymous(locals) {
|
||||
exports.pages.chat = function anonymous(locals) {
|
||||
var buf = [];
|
||||
with (locals || {}) {
|
||||
buf.push('<section class="page chat"><section class="conversation"><header><img class="avatar"/><h1 class="name"></h1><div class="tzo"></div><button class="call">call</button><video class="remoteVideo"></video></header><ul class="messages scroll-container"></ul><div class="chatBox"><form><textarea name="chatInput" type="text" placeholder="Send a message..." autocomplete="off"></textarea></form></div></section></section>');
|
||||
buf.push('<section class="page chat"><section class="conversation"><header><img class="avatar"/><h1 class="name"></h1><div class="tzo"></div><button class="call">call</button></header><ul class="messages scroll-container"></ul><div class="chatBox"><form><textarea name="chatInput" type="text" placeholder="Send a message..." autocomplete="off"></textarea></form></div></section></section>');
|
||||
}
|
||||
return buf.join("");
|
||||
};
|
||||
|
@ -5,6 +5,7 @@ body
|
||||
| You're currently
|
||||
strong disconnected
|
||||
button.reconnect Reconnect
|
||||
header#calls
|
||||
aside#menu
|
||||
nav.main
|
||||
li
|
||||
|
7
clientapp/templates/includes/call.jade
Normal file
7
clientapp/templates/includes/call.jade
Normal file
@ -0,0 +1,7 @@
|
||||
.call
|
||||
img.callerAvatar
|
||||
h1.caller
|
||||
span.callerName
|
||||
span.callerNumber
|
||||
h2.callTime
|
||||
.callActions
|
@ -5,7 +5,6 @@ section.page.chat
|
||||
h1.name
|
||||
.tzo
|
||||
button.call call
|
||||
video.remoteVideo
|
||||
ul.messages.scroll-container
|
||||
.chatBox
|
||||
form
|
||||
|
28
clientapp/views/call.js
Normal file
28
clientapp/views/call.js
Normal file
@ -0,0 +1,28 @@
|
||||
/*global $*/
|
||||
"use strict";
|
||||
|
||||
var _ = require('underscore');
|
||||
var HumanView = require('human-view');
|
||||
var templates = require('../templates');
|
||||
|
||||
|
||||
module.exports = HumanView.extend({
|
||||
template: templates.includes.call,
|
||||
classBindings: {
|
||||
state: ''
|
||||
},
|
||||
render: function () {
|
||||
this.renderAndBind();
|
||||
// register bindings for sub model
|
||||
this.registerBindings(this.model.contact, {
|
||||
textBindings: {
|
||||
displayName: '.callerName'
|
||||
},
|
||||
srcBindings: {
|
||||
avatar: '.callerAvatar'
|
||||
}
|
||||
});
|
||||
|
||||
return this;
|
||||
}
|
||||
});
|
@ -5,6 +5,7 @@ var HumanView = require('human-view');
|
||||
var templates = require('../templates');
|
||||
var ContactListItem = require('../views/contactListItem');
|
||||
var MUCListItem = require('../views/mucListItem');
|
||||
var CallView = require('../views/call');
|
||||
|
||||
|
||||
module.exports = HumanView.extend({
|
||||
@ -26,6 +27,7 @@ module.exports = HumanView.extend({
|
||||
this.renderAndBind();
|
||||
this.renderCollection(me.contacts, ContactListItem, this.$('#roster nav'));
|
||||
this.renderCollection(me.mucs, MUCListItem, this.$('#bookmarks nav'));
|
||||
this.renderCollection(me.calls, CallView, this.$('#calls'));
|
||||
return this;
|
||||
},
|
||||
handleReconnect: function (e) {
|
||||
|
1362
npm-shrinkwrap.json
generated
1362
npm-shrinkwrap.json
generated
File diff suppressed because it is too large
Load Diff
@ -13,7 +13,7 @@
|
||||
"express": "3.3.7",
|
||||
"getconfig": "0.0.5",
|
||||
"jade": "0.35.0",
|
||||
"moonboots": "0.7.0",
|
||||
"moonboots": "1.0.0",
|
||||
"helmet": "0.1.0",
|
||||
"node-uuid": "1.4.1",
|
||||
"semi-static": "0.0.4",
|
||||
|
138
public/css/app/callbar.styl
Normal file
138
public/css/app/callbar.styl
Normal file
@ -0,0 +1,138 @@
|
||||
@import _mixins
|
||||
@import _variables
|
||||
|
||||
body
|
||||
position: relative !important
|
||||
-webkit-transition: top 1s
|
||||
|
||||
&.candybarVisible
|
||||
top: 100px
|
||||
|
||||
#calls
|
||||
position: fixed
|
||||
top: -120px
|
||||
left: 0px
|
||||
-webkit-transition: background-color 1s
|
||||
-webkit-transition: top 1s
|
||||
width: 100%
|
||||
height: 80px
|
||||
padding: 10px
|
||||
z-index: 1000
|
||||
|
||||
&.visible
|
||||
top: 0px
|
||||
|
||||
&.havatar
|
||||
.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%
|
||||
|
||||
nav
|
||||
float: left
|
||||
|
||||
button
|
||||
min-width: auto
|
||||
background-color: rgba(255,255,255,.3)
|
||||
gradient(rgba(255,255,255,.5),rgba(0,0,0,.1))
|
||||
border:
|
||||
top: 1px solid rgba(255,255,255,.6)
|
||||
bottom: 1px solid rgba(0,0,0,.1)
|
||||
left: 1px solid rgba(255,255,255,.2)
|
||||
right: 1px solid rgba(255,255,255,.2)
|
||||
width: 100px
|
||||
margin-right: 10px
|
||||
font-size: 16px
|
||||
color: rgba(0,0,0,.75)
|
||||
text_shadow(rgba(255,255,255,.5),0,1px,0)
|
||||
float: left
|
||||
shadow(rgba(0,0,0,.3), 0, 1px, 3)
|
||||
&:hover
|
||||
background-color: rgba(255,255,255,.4)
|
||||
&:active
|
||||
inner_shadow(rgba(0,0,0,.2),0,1px,3)
|
||||
padding-top: 11px
|
||||
padding-bottom: 9px
|
||||
border:
|
||||
bottom: 1px solid rgba(255,255,255,1)
|
||||
top: 1px solid rgba(0,0,0,.2)
|
||||
|
||||
.callerAvatar
|
||||
float: left
|
||||
width: 65px
|
||||
height: 65px
|
||||
border: 5px solid #eee
|
||||
margin-right: 10px
|
||||
|
||||
.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
|
||||
font-size: 20px
|
||||
padding-bottom: 0px
|
||||
border-bottom: 2px groove rgba(255,255,255,.4)
|
||||
|
||||
.callerName
|
||||
display: inline
|
||||
.callerNumber
|
||||
display: inline
|
||||
margin-left: 10px
|
||||
|
||||
.callTime
|
||||
position: absolute
|
||||
top: 12px
|
||||
right: 40px
|
||||
font-size: 20px
|
||||
margin: 0
|
@ -1027,3 +1027,138 @@ button:hover,
|
||||
a.button:hover {
|
||||
background: #007aa7;
|
||||
}
|
||||
body {
|
||||
position: relative !important;
|
||||
-webkit-transition: top 1s;
|
||||
}
|
||||
body.candybarVisible {
|
||||
top: 100px;
|
||||
}
|
||||
#calls {
|
||||
position: fixed;
|
||||
top: -120px;
|
||||
left: 0px;
|
||||
-webkit-transition: background-color 1s;
|
||||
-webkit-transition: top 1s;
|
||||
width: 100%;
|
||||
height: 80px;
|
||||
padding: 10px;
|
||||
z-index: 1000;
|
||||
}
|
||||
#calls.visible {
|
||||
top: 0px;
|
||||
}
|
||||
#calls.havatar .callActions {
|
||||
left: 100px;
|
||||
}
|
||||
#calls.havatar .caller {
|
||||
margin-left: 90px;
|
||||
}
|
||||
#calls.incoming {
|
||||
background: #00f;
|
||||
}
|
||||
#calls.incoming .callTime {
|
||||
display: none;
|
||||
}
|
||||
#calls.incoming .callerName:before {
|
||||
content: "Incoming: ";
|
||||
}
|
||||
#calls.waiting .spinner div {
|
||||
background-color: #fff;
|
||||
}
|
||||
#calls.calling .callTime {
|
||||
display: none;
|
||||
}
|
||||
#calls.calling .callerName:before {
|
||||
content: "Calling: ";
|
||||
}
|
||||
#calls.active .callerName:before {
|
||||
content: "On Call: ";
|
||||
}
|
||||
#calls.remote .callTime {
|
||||
display: none;
|
||||
}
|
||||
#calls.ending .callerName:before {
|
||||
content: "Call ending with: ";
|
||||
}
|
||||
#calls .callActions {
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
top: 50px;
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
#calls nav {
|
||||
float: left;
|
||||
}
|
||||
#calls button {
|
||||
min-width: auto;
|
||||
background-color: rgba(255,255,255,0.3);
|
||||
rgba(0,0,0,0.1)
|
||||
width: 100px;
|
||||
margin-right: 10px;
|
||||
font-size: 16px;
|
||||
color: rgba(0,0,0,0.75);
|
||||
rgba(255,255,255,0.5)
|
||||
float: left;
|
||||
rgba(0,0,0,0.3)
|
||||
}
|
||||
#calls button border:top: 1pxsolid rgba(255,
|
||||
#calls button 255,
|
||||
#calls button 255,
|
||||
#calls button 0.6) {
|
||||
bottom: 1px solid rgba(0,0,0,0.1);
|
||||
left: 1px solid rgba(255,255,255,0.2);
|
||||
right: 1px solid rgba(255,255,255,0.2);
|
||||
}
|
||||
#calls button:hover {
|
||||
background-color: rgba(255,255,255,0.4);
|
||||
}
|
||||
#calls button:active {
|
||||
rgba(0,0,0,0.2)
|
||||
padding-top: 11px;
|
||||
padding-bottom: 9px;
|
||||
}
|
||||
#calls button:active border:bottom: 1pxsolid rgba(255,
|
||||
#calls button:active 255,
|
||||
#calls button:active 255,
|
||||
#calls button:active 1) {
|
||||
top: 1px solid rgba(0,0,0,0.2);
|
||||
}
|
||||
#calls .callerAvatar {
|
||||
float: left;
|
||||
width: 65px;
|
||||
height: 65px;
|
||||
border: 5px solid #eee;
|
||||
margin-right: 10px;
|
||||
}
|
||||
#calls .callerName,
|
||||
#calls .callTime {
|
||||
font-weight: bold;
|
||||
color: #fff;
|
||||
rgba(0,0,0,0.7)
|
||||
line-height: 1;
|
||||
}
|
||||
#calls .caller {
|
||||
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;
|
||||
}
|
||||
#calls .callerNumber {
|
||||
display: inline;
|
||||
margin-left: 10px;
|
||||
}
|
||||
#calls .callTime {
|
||||
position: absolute;
|
||||
top: 12px;
|
||||
right: 40px;
|
||||
font-size: 20px;
|
||||
margin: 0;
|
||||
}
|
||||
|
@ -8,3 +8,4 @@
|
||||
@import 'app/settings'
|
||||
@import 'app/aux'
|
||||
@import 'app/forms'
|
||||
@import 'app/callbar'
|
||||
|
@ -1,5 +1,5 @@
|
||||
CACHE MANIFEST
|
||||
# 0.0.1 1381823999689
|
||||
# 0.0.1 1381864472792
|
||||
|
||||
CACHE:
|
||||
/app.js
|
||||
|
@ -38,7 +38,7 @@ var clientApp = new Moonboots({
|
||||
});
|
||||
|
||||
if (config.isDev) {
|
||||
clientApp.config.beforeBuild = function () {
|
||||
clientApp.config.beforeBuildJS = function () {
|
||||
var clientFolder = __dirname + '/clientapp';
|
||||
templatizer(clientFolder + '/templates', clientFolder + '/templates.js');
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user