<!DOCTYPE html>
<html>
<head>
<title>Tel App V2</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
<script src="libs/fullscreen.js"></script>
<script src="data.js"></script>
<link rel="stylesheet" href="libs/animate.min.css">
<link rel="stylesheet" href="libs/fontawesomeligth.min.css">
<link rel="stylesheet" href="libs/bootstrap.min.css">
<link rel="stylesheet" href="libs/roboto.css">
<link rel="stylesheet" href="files/styles.css">
</head>
<body>
<div id="app"></div>
<script src="libs/vue.min.js"></script>
<!-- Template loader: fetches templates from files/ then loads components -->
<script src="files/template-loader.js"></script>
</body>
</html>
var MobileFullPageImg = {
name: 'MobileFullPageImg',
template: '#tpl-mobile-full-page-img',
props: {
imgs: { type: Array },
nextscreen: {type: String, default: 'main'},
},
data: function () { return {
index: 0,
}},
computed: {
},
created: function () {
console.log(this.imgs);
},
methods: {
nextimg: function () {
this.index = (this.index + 1) % this.imgs.length;
if (!this.index) {
this.next();
}
},
next: function () {
this.$emit('setscreen', this.nextscreen, 60, {}, function () {}, true);
},
stopPropagation: function (e) {
e.stopPropagation();
}
}
};
var MobileLock = {
name: 'MobileLock',
template: '#tpl-mobile-lock',
props: {
unlockpos: { type: String, default: 'TOPRIGHT' },
mode: { type: String, default: 'TELIN'},
delay: { type: Number, default: 0},
nextscreen: { type: String, default: 'main'}
},
computed: {
unlockClass: function () { return {
'top-right': this.unlockpos == 'TOPRIGHT',
'top-left': this.unlockpos == 'TOPLEFT',
'bottom-right': this.unlockpos == 'BOTTOMRIGHT',
'bottom-left': this.unlockpos == 'BOTTOMLEFT',
}}
},
created: function () {
},
methods: {
stopPropagation: function (e) {
e.stopPropagation();
}
}
};
var MobileMain = {
name: 'MobileMain',
template: '#tpl-mobile-main',
props: {
background: {type: String, default: ''},
unlock: { type: Boolean, default: false},
disablenotif: { type: Boolean, default: false},
hour: String,
date: String,
icons: Array,
icons2: Array,
notifs: Array,
notifdelay: {type: Number, default: 0},
mode: {type: String, default: 'TELIN'},
nextscreen: { type: String, default: 'lock' },
color: { type: String, default: 'darkgreen' },
nonotif: { type: Boolean, default: false },
maxnotifs: { type: Number, default: 3 },
unlockfailed: { type: Number, default: 0 },
},
data: function () {
return {
locked: 0,
code: '',
nnotifs: [],
notif_index: 0,
nextdisabled: false,
shutdown: false,
shutdownmenu: false,
unlocktry: 0,
wrongCode: false,
};
},
computed: {
setlockone: function (d) {
this.locked = 1;
},
opac: function () {
if (this.hour && !this.locked) {
return true;
}
if (this.nonotif) { return false; }
if (this.unlock && (this.locked == 1)) {
return false;
}
var o = false;
if (!o && (!this.unlock || this.locked == 2)) {
for (var j = 0; j < this.nnotifs.length; j++) {
if (this.nnotifs[j].visible) {
o = true;
break;
}
}
}
return o;
}
},
mounted: function () {
if (!this.nonotif) {
this.nnotifs = (this.notifs && this.notifs.concat([])) || [];
this.nnotifs.forEach(function (n) { delete n.visible; });
this.notif_index = 0;
}
console.log(this.unlock);
if (!this.nonotif && this.notifdelay && this.notifs && this.notifs.length) {
this.showNotifDelay(this.notifdelay * 1000);
}
},
methods: {
showNotifDelay: function (delai) {
var that = this;
this.nextdisabled = true;
setTimeout(function () {
that.nextdisabled = false;
that.showNotif();
}, delai)
},
showNotif: function () {
if (this.nextdisabled) { return; }
var cptvisible = 0;
for (var u = this.notif_index - 1; u >= 0 ; u--) {
var n = this.nnotifs[u];
if (n.visible) cptvisible += 1;
if (cptvisible > this.maxnotifs - 1) {
n.visible = false;
Vue.set(this.nnotifs, u, n);
}
}
if (this.nnotifs[this.notif_index]) {
for (var ni = this.notif_index - this.maxnotifs; ni >= 0; ni--) {
var n = this.nnotifs[ni];
if (n) {
n.visible = false;
Vue.set(this.nnotifs, ni, n);
}
}
var that = this;
console.log(that);
var n = that.nnotifs[that.notif_index];
n.visible = true;
if (n.mms) {
that.notiftop = '10vh';
}
Vue.set(that.nnotifs, that.notif_index, n);
that.notif_index += 1;
if (n.nextdelay && n.nextdelay != 0) {
setTimeout(function () {
that.showNotif();
}, n.nextdelay * 1000)
}
} else {
if (this.unlock && !this.locked) {
this.locked = 1;
} else {
this.$emit('setscreen', this.nextscreen, 60, {}, function () {}, true);
}
}
},
hideLastNotif: function () {
for (var i = 0; i < this.nnotifs.length; i++) {
var n = this.nnotifs[i];
if (n.visible) {
n.visible = false;
Vue.set(this.nnotifs, i , n);
break;
}
}
},
hideNotif: function (i) {
i = this.nnotifs.length - (i + 1); // reverse
var n = this.nnotifs[i];
if (n) {
n.visible = false;
Vue.set(this.nnotifs, i, n);
}
},
addcode: function () {
if (this.code.length < 3) {
this.code += '\u25CF';
} else {
if (this.code.length < 4)
this.code += '\u25CF';
var that = this;
setTimeout(function() {
that.unlocktry++;
if (that.unlocktry > that.unlockfailed) {
that.locked = 2;
} else {
that.wrongCode = true;
setTimeout(function() {
that.wrongCode = false;
that.code = '';
}, 500);
}
}, 300);
}
},
showMMS: function(mms) {
this.$emit('setdata', 'imgs', { 'img': [mms], nextscreen: 'sms'});
this.$emit('setscreen', 'imgs', 10);
}
}
};
var MobileRepondeurList = {
name: 'MobileRepondeurList',
template: '#tpl-mobile-repondeur-list',
props: {
nextscreen: { type: String, default: 'main'},
directory: { type: Array, default: function () { return []; } }
},
data: function () {
return {
deletediag: false,
opac: false,
entries: [],
selected: [],
interval: null,
counteri: 0,
counter: '0:00',
todelete: -1,
};
},
computed : {
},
beforeDestroy: function () {
if (this.interval) {
clearInterval(this.interval);
}
},
mounted: function () {
this.selected = [];
this.entries = [];
this.directory = this.directory || [];
for (var i = 0; i < this.directory.length; i++) {
this.selected.push(false);
this.entries.push(this.directory[i]);
}
},
methods: {
get_time_str: function(timer_val) {
var seconds = (timer_val % 60);
if (seconds < 10) { seconds = '0' + seconds; }
var timer_str = Math.floor(timer_val / 60) + ':' + seconds
return timer_str;
},
deletemsg: function () {
var i = this.todelete;
this.selected.splice(i, 1);
this.entries.splice(i, 1);
},
openTel: function (name) {
var that = this;
this.$emit('setscreen', 'tel', 10, { 'tel': { mode: 'TELOUT2', outmode: true, name: name } }, function () {
});
},
playEntry: function (i) {
for (var j = 0; j < this.directory.length; j++) {
if (i != j) {
Vue.set(this.selected, j, false);
}
}
Vue.set(this.selected, i, !this.selected[i]);
this.counteri = 1;
if (!this.interval) {
var that = this;
this.interval = setInterval(function () {
that.counter = that.get_time_str(that.counteri);
that.counteri ++;
}, 1000);
}
},
close: function () {
this.$emit('setscreen', 'main', 10);
},
stopPropagation: function (e) {
e.stopPropagation();
}
}
};
function sms_autosize(){
var el = document.querySelector('textarea');
setTimeout(function(){
el.style.cssText = 'height:auto;';
el.style.cssText = 'min-height:' + el.scrollHeight + 'px';
}, 0);
}
var sms_deleteTxtAnimInput = function (nbchar, id, cb, interval) {
interval = interval || 50;
var txt_index = 0;
var timer;
function writeTxt() {
if (nbchar <= 0) {
clearInterval(timer);
timer = null;
setTimeout(function () {
if (cb) { cb(); }
}, 500);
return;
}
if (!timer) {
timer = setInterval(writeTxt, interval);
return;
}
var rand_time = Math.floor(Math.random() * interval);
setTimeout(function () {
var elem = document.getElementById(id);
elem.focus();
var v = elem.value;
elem.value = elem.value.slice(0, -3);
elem.scrollLeft = elem.scrollWidth;
nbchar -= 3;
}, rand_time);
}
writeTxt();
};
var sms_writeTxtAnimInput = function (txt, id, cb, cb2, interval) {
interval = interval || 50;
var txt_index = 0;
var timer;
function writeTxt() {
if (txt_index >= txt.length) {
clearInterval(timer);
timer = null;
setTimeout(function () {
if (cb) { cb(); }
}, 500);
return;
}
if (!timer) {
timer = setInterval(writeTxt, interval);
return;
}
var rand_time = Math.floor(Math.random() * interval);
setTimeout(function () {
var elem = document.getElementById(id);
elem.focus();
var v = elem.value;
var c = txt[txt_index];
if (c) {
elem.value = v + c;
}
elem.scrollLeft = elem.scrollWidth;
cb2();
txt_index += 1;
}, rand_time);
}
writeTxt();
};
function sms_get_time_str(timer_val) {
var seconds = (timer_val % 60);
if (seconds < 10) { seconds = '0' + seconds; }
var timer_str = Math.floor(timer_val / 60) + ':' + seconds
return timer_str;
}
var MobileSms = {
name: 'MobileSms',
template: '#tpl-mobile-sms',
props: {
msgs: { type: Array},
send_msgs: { type: Array},
writespeed: { type: Number, default: 80 },
dots: { type: Boolean, default: false },
nextscreen: { type: String, default: 'lock'},
nextdata: { type: Object, default: function () { return {} }},
dest: { type: String, default: 'Inconnu'},
color1: { type: String, default: '#00A192'},
color2: { type: String, default: 'white'},
color3: { type: String, default: 'red'},
full: {type: Boolean},
photodata: {type: String}
},
data: function () {
return {
opac: false,
hasselection: false,
deletediag: false,
keyboard: false,
vocalkeyboard: false,
loading: false,
send_msgs_data: this.send_msgs ? this.send_msgs.concat([]) : [],
msgs_data: this.msgs ? this.msgs.concat([]) : [],
deletesomemsg: false,
dotsbox: false,
counter: '',
timer: null,
counter_i: 0,
};
},
computed : {
},
created: function () {
var uid = 0;
this.msgs.forEach(function (m) { m.id = uid++; });
this.send_msgs.forEach(function (m) { m.id = uid++; });
},
mounted: function () {
if (this.full) {
this.msgs_data = this.msgs_data.concat(this.send_msgs_data);
}
var that = this;
this.msgs.forEach(function (m, i) {
delete m.selected;
});
this.send_msgs.forEach(function (m) {
delete m.selected;
});
var that = this;
this.$nextTick(function () {
document.getElementById('msg' + (that.msgs_data.length - 1)).scrollIntoView();
});
},
methods: {
playmsg: function (msg) {
var that = this;
this.$set(msg, 'playing', true);
setTimeout(function () {
that.$set(msg, 'playing', false);
}, 4000);
},
selectMsg: function (msg) {
if (msg.deletable) {
this.$set(msg, 'selected', true);
this.hasselection = true;
this.$forceUpdate();
}
},
scrollDown: function (smooth) {
var that = this;
var option = {};
if (smooth) {
option = {behavior: "smooth"};
}
setTimeout(function () {
var el = document.getElementById('msg' + (that.msgs_data.length - 1))
if (el) { el.scrollIntoView(option); }
}, 10);
setTimeout(function () {
var el = document.getElementById('msg' + (that.msgs_data.length - 1));
if (el) {
el.scrollIntoView(option);
}
}, 300);
},
showMMS: function(mms) {
this.$emit('setdata', 'imgs', { 'imgs': [mms], nextscreen: 'sms'});
this.$emit('setscreen', 'imgs', 10);
},
startRecord: function () {
this.counter = '00:00',
this.counter_i = 0;
var that = this;
clearInterval(this.timer);
this.timer = setInterval(function () {
that.counter_i ++;
that.counter = sms_get_time_str(that.counter_i);
}, 1000);
},
stopRecord: function (e) {
var that = this;
clearInterval(this.timer);
setTimeout(function () {
that.sendMsg(e,20);
}, 10)
setTimeout(function () {
that.counter = '';
that.counter_i = 0;
}, 300)
},
showKeyboard: function (e) {
if (e) e.stopPropagation();
if (this.send_msgs_data[0].wave) {
this.startRecord();
return;
}
if (this.vocal) {
this.showVocalKeyboard(e);
return;
}
if (this.vocalkeyboard) { return; }
if (this.keyboard && !this.disablenext) {
this.keyboard = false;
this.scrollDown(true);
return;
}
this.keyboard = true;
this.scrollDown();
},
showVocalKeyboard: function (e) {
e.stopPropagation();
if (this.keyboard) { return; }
if (this.vocalkeyboard && !this.disablenext) {
this.vocalkeyboard = false;
return;
}
this.vocalkeyboard = true;
var that = this;
this.scrollDown();
},
writeTxt: function (e) {
if (e) { e.stopPropagation(); }
console.log(this.disablenext);
if (!this.disablenext) {
this.disablenext = true;
var that = this;
var elem = document.getElementById('txtinput');
var msg = this.send_msgs_data[0] || {};
if (!msg.txt) {
this.disablenext = false;
return;
}
if (msg.dest || msg.written || msg.wave) {
this.disablenext = false;
if (msg.wave) {
this.sendMsg(e);
}
return;
}
if (!msg.splitted) {
if (msg.msgsav) { msg.txt = msg.msgsav; }
msg.splitted = msg.txt.split('@@');
msg.spindex = 0;
msg.msgsav = msg.txt;
}
if (msg.spindex >= msg.splitted.length) {
this.disablenext = false;
msg.written = true;
return;
}
var txtar = msg.splitted[msg.spindex];
console.log(txtar);
if (!txtar) {
that.disablenext = false;
that.vocalkeyboard = false;
return;
}
msg.spindex += 1;
if (txtar[0] == '$') {
txtar = txtar.slice(1);
sms_deleteTxtAnimInput(Number(txtar), 'txtinput', function () {
that.disablenext = false;
that.send_msgs_data[0].txt = elem.value;
}, 110);
} else {
sms_writeTxtAnimInput(txtar || '', 'txtinput', function () {
elem.scrollLeft = elem.scrollWidth; elem.scrollTop = elem.scrollHeight;
that.disablenext = false;
that.send_msgs_data[0].txt = elem.value;
}, function () {
that.send_msgs_data[0].txt = elem.value;
sms_autosize();
that.scrollDown();
}, that.writespeed);
}
}
},
sendMsg: function (e, delai) {
var that = this;
var msg = that.send_msgs_data[0];
if (!msg || that.disablenext) { return; }
msg.txt = msg.txt.replace(/[\<\>]/g, '');
msg.txt = msg.txt.replace(/@@/g, '');
msg.txt = msg.txt.replace(/\$\d+/g, '');
delete msg.splitted;
delete msg.spindex;
if (!msg || msg.dest) {
return;
}
that.send_msgs_data = that.send_msgs_data.slice(1);
this.loading = true;
setTimeout(function () {
that.disablenext = false;
var e = document.getElementById('txtinput');
if (e) { e.value = ''; }
that.keyboard = false;
that.vocalkeyboard = false;
that.loading = false;
if (msg && (msg.txt || msg.mms)) {
msg.written = false;
that.msgs_data = that.msgs_data.concat([msg]);
}
sms_autosize();
that.scrollDown(true);
}, delai || 1300);
if (e) { e.stopPropagation(); }
},
previousMsg: function (e) {
var that = this;
if (that.msgs_data.length > that.msgs.length) {
var msg = that.msgs_data.pop();
that.send_msgs_data.unshift(msg);
}
},
markAsRead: function (e) {
var that = this;
that.msgs_data.forEach(function (msg) {
that.$set(msg, 'readmark', 'lu');
});
},
clearLastMsg: function (e) {
var that = this;
var lastmsg = that.msgs_data.at(-1);
that.$set(lastmsg, 'cleared', true);
},
receiveMsg: function (e) {
var that = this;
var msg = that.send_msgs_data[0];
if (!msg) {
if (!that.hasselection) {
this.$emit('setscreen', this.nextscreen, 10, this.nextdata);
}
return;
}
delete msg.splitted;
delete msg.spindex;
if (msg.dest || !msg.txt) {
that.keyboard = false;
if (msg.dest && that.dots && !that.dotsbox) {
that.dotsbox = true;
} else {
that.dotsbox = false;
if (msg.txt || msg.mms) {
that.msgs_data = that.msgs_data.concat([msg]);
}
that.send_msgs_data = that.send_msgs_data.slice(1);
}
} else {
that.showKeyboard(e);
return;
}
this.scrollDown(true);
if (e) { e.stopPropagation(); }
},
hideAll: function () {
var that = this;
setTimeout(function () {
if (that.deletesomemsg) {
that.msgs_data = that.msgs_data.filter(function (m) { return !m.deletable || !m.selected; });
} else {
that.msgs_data = [];
}
that.hasselection = false;
}, 500);
},
openTel: function () {
var that = this;
this.$emit('setscreen', 'tel', 10, { 'tel': { mode: 'TELOUT2', outmode: true, name: this.dest } }, function () {
});
},
showDeleteDiag: function (msg, event) {
var ds = this.msgs_data.filter(function (m) { return m.deletable && m.selected; });
this.deletesomemsg = true;
if (ds && ds.length) {
this.opac = true;
this.deletediag = true;
}
if (msg) { event.stopPropagation(); }
return;
},
stopPropagation: function (e) {
e.stopPropagation();
}
}
};
var MobileSmsDir = {
name: 'MobileSmsDir',
template: '#tpl-mobile-sms-dir',
props: {
nextscreen: { type: String, default: 'main'},
directory: { type: Array, default: function () { return []; } }
},
data: function () {
return {
entries: [],
selected: []
};
},
computed : {
},
mounted: function () {
this.selected = [];
this.entries = [];
this.directory = this.directory || [];
for (var i = 0; i < this.directory.length; i++) {
this.selected.push(false);
this.entries.push(this.directory[i]);
}
},
methods: {
selectEntry: function (i) {
Vue.set(this.selected, i, !this.selected[i]);
var entry = this.entries[i];
this.$emit('setscreen', 'sms', 400);
},
stopPropagation: function (e) {
e.stopPropagation();
}
}
};
var MobileScrollImg = {
name: 'MobileScrollImg',
template: '#tpl-mobile-scroll-img',
props: {
imgs: { type: Array },
img: { type: Array },
head: { type: Boolean },
topimg: { type: String },
title: { type: String },
scroll: { type: Boolean },
cam: { type: Boolean },
loop: { type: Boolean },
nextscreen: {type: String, default: 'lock'},
},
data: function () {
return {
share: false,
flash: false,
photodata: null,
showphoto: true,
imgi: 0,
};
},
computed: {
},
created: function () {
},
mounted: function () {
if (this.cam) {
this.initCam();
}
},
methods: {
stopPropagation: function (e) {
e.stopPropagation();
},
nextScreen: function () {
},
setflash: function() {
var that = this;
that.flash = true;
setTimeout(function () { that.flash = false;}, 600)
setTimeout(function () { that.cam = false;}, 900)
},
nextimg: function () {
if (!this.loop && (this.imgi < this.imgs.length - 1)) {
this.imgi = (this.imgi + 1);
} else {
this.imgi = (this.imgi + 1)%this.imgs.length;
}
},
initCam: function () {
var that = this;
var streaming = false,
video = document.querySelector('#video'),
cover = document.querySelector('#cover'),
canvas = document.querySelector('#canvas'),
photo = document.querySelector('#photo'),
startbutton = document.querySelector('#startbutton'),
width = 640;
var height = 0;
navigator.getMedia = ( navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.msGetUserMedia);
navigator.mediaDevices.getUserMedia({
video: {
facingMode: 'environment'
},
audio: false
}).then(
function(stream) {
if (navigator.mozGetUserMedia) {
video.mozSrcObject = stream;
} else {
try {
video.srcObject = stream;
}
catch (error) {
video.src = window.URL.createObjectURL(stream);
}
}
video.play();
},
function(err) {
console.log("An error occured! " + err);
}
);
video.addEventListener('canplay', function(ev){
if (!streaming) {
height = video.videoHeight / (video.videoWidth/width);
video.setAttribute('width', width);
video.setAttribute('height', height);
canvas.setAttribute('width', width);
canvas.setAttribute('height', height);
streaming = true;
}
}, false);
function takepicture() {
canvas.width = width;
canvas.height = height;
canvas.getContext('2d').drawImage(video, 0, 0, width, height);
var data = canvas.toDataURL('image/png');
that.photodata = data;
}
startbutton.addEventListener('click', function(ev){
takepicture();
ev.preventDefault();
}, false);
}
}
};
var MobileTel = {
name: 'MobileTel',
template: '#tpl-mobile-tel',
props: {
name: { type: String, default: 'Numéro inconnu' },
dcall: { type: String},
dcallimg: { type: String},
notif: { type: Object },
waitforcounter: { type: Number, default: 0 },
avatar: { type: String, default: '' },
avatar_bg: { type: String, default: ''},
force_avatar_bg: { type: Boolean, default: false },
mode: { type: String, default: 'TELIN' },
misscalldelay: { type: Number, default: 0},
offdelay: { type: Number, default: 7},
sslider: { type: Boolean, default: false },
bt: { type: Boolean, default: false },
nextscreen: { type: String, default:'' },
outmode: { type: Boolean, default: false },
color1: { type: String, default:'#000' },
color2: { type: String, default:'#444' },
emptyh: { type: String },
emptyh2: { type: String },
videoin: { type: Boolean },
greencall: { type: Boolean },
},
data: function () { return {
phonein: true,
endcall: false,
timer: null,
counter: 0,
statut:'',
nosnd: false,
hp: false,
nomic: false,
showdcall: false,
displayname: this.name,
lastname: '',
lastcounter: 0,
lastavatar: '',
lastavatar_bg: '',
fullgreen: false
}},
mounted: function () {
this.init();
},
computed: {
},
methods: {
init: function () {
console.log('mount', this.avatar);
this.statut = 'Appel entrant';
this.displayname = this.name;
this.lastavatar_bg = '';
this.lastavatar = '';
this.fullgreen = false;
if (this.mode == 'TELIN' || this.mode == 'SMSTEL') {
if (this.calling) {
return;
} else {
this.statut = 'Appel entrant';
this.endcall = false;
this.missedCall(this.misscalldelay);
}
} else if (this.outmode) {
this.statut = 'Connexion';
this.endcall = false;
this.nextPhoneStatut( this.waitforcounter || 600)
}
else if (this.mode == 'TELOUT2') {
this.phonein = false;
this.statut = 'Appel en cours';
this.timer = true;
}
},
get_time_str: function(timer_val) {
var seconds = (timer_val % 60);
if (seconds < 10) { seconds = '0' + seconds; }
var timer_str = Math.floor(timer_val / 60) + ':' + seconds
return timer_str;
},
doMissedCall: function () {
this.missedCall(0.01);
},
missedCall: function (delai) {
if (!delai || delai == '0') { return; }
var that = this;
setTimeout(function () {
if (that.endcall || !that.phonein) { return; }
that.endcall = true;
that.statut = "Appel manqué";
that.$emit('setscreen', 'main', 2200, {}, function () {
that.$emit('setscreen', 'lock', that.offdelay * 1000 || 3000, {}, function () {
that.endcall = false;
});
});
}, delai * 1000);
},
rejectCall: function () {
this.endcall = true;
this.statut = "Appel refusé";
var that = this;
that.$emit('setscreen', 'main', 1000, {}, function () {
that.$emit('setscreen', 'lock', that.offdelay * 1000 || 3000, {}, function () {
that.endcall = false;
});
});
},
nextPhoneStatut: function (waittime) {
if (this.timer) {
if (this.lastname) {
this.counter = this.lastcounter;
this.displayname = this.lastname;
this.avatar_bg = this.lastavatar_bg;
this.avatar = this.lastavatar;
this.lastcounter = 0;
this.lastname = '';
return;
}
clearInterval(this.timer);
this.timer = null;
this.counter = 0;
this.endcall = true;
this.statut = "Fin d'appel";
var that = this;
if (that.notif && that.notif.active) {
that.$emit('setdata', 'sms', {calling: false, full: true});
that.$emit('setscreen', 'sms', 1000, {}, function () {
that.endcall = false;
});
} if (that.nextscreen) {
setTimeout(function () {
that.$emit('setscreen', that.nextscreen, 1000, {}, function () {});
}, 50);
} else {
that.$emit('setscreen', 'main', 1000, {}, function () {
that.$emit('setscreen', 'lock', that.offdelay * 1000 || 3000, {}, function () {
that.endcall = false;
});
});
}
} else if (!this.timer && !this.endcall) {
this.timer = true;
this.phonein = false;
var that = this;
setTimeout(function () {
if (that.greencall) {
setTimeout(function () {
that.fullgreen = true;
}, 100);
return;
}
if (that.endcall) { return; }
that.counter = 1;
that.statut = '0:01';
if (that.timer) {
clearInterval(that.timer);
that.timer = null;
}
that.timer = setInterval(function () {
that.counter += 1;
that.statut = that.get_time_str(that.counter);
}, 1000);
}, 3000 + waittime);
}
},
showNotif: function (e) {
if (this.notif) {
Vue.set(this.notif, 'visible', true);
}
},
showDoubleCall: function (e) {
this.showdcall = true;
},
answerdcall: function () {
this.showdcall = false;
this.statut = "Connexion";
this.lastcounter = this.counter;
this.lastname = this.displayname;
this.displayname = this.dcall;
this.lastavatar_bg = this.avatar_bg;
this.lastavatar = this.avatar;
this.avatar_bg = '';
this.avatar = '';
clearInterval(this.timer);
this.timer = null;
this.counter = 0;
this.nextPhoneStatut(1);
},
rejectdcall: function () {
this.showdcall = false;
},
hideNotif: function (e) {
var that = this;
this.$emit('setscreen', 'sms', 0, {}, function () {
Vue.set(that.notif, 'visible', false);
});
},
stopPropagation: function (e) {
e.stopPropagation();
}
}
};
var writeTxtAnimInputCompose = function (txt, id, cb, cb2, interval, ontouch) {
interval = interval || 50;
var txt_index = 0;
var timer;
if (ontouch) {
var elem = document.getElementById(id);
elem.focus();
var v = elem.value + '';
var c = txt[v.length];
console.log(c);
if (c !== undefined) {
elem.value = v + c;
elem.scrollLeft = elem.scrollWidth;
if (cb2) { cb2(); }
if (c == ' ') {
writeTxtAnimInputCompose(txt, id, cb, cb2, interval, ontouch)
}
} else {
if (cb) { cb(); }
}
return;
}
function writeTxt() {
if (txt_index >= txt.length) {
clearInterval(timer);
timer = null;
setTimeout(function () {
if (cb) { cb(); }
}, 500);
return;
}
if (!timer) {
timer = setInterval(writeTxt, interval);
return;
}
var rand_time = Math.floor(Math.random() * interval);
setTimeout(function () {
var elem = document.getElementById(id);
elem.focus();
var v = elem.value;
var c = txt[txt_index];
if (c) {
elem.value = v + c;
}
elem.scrollLeft = elem.scrollWidth;
cb2(txt_index);
txt_index += 1;
}, rand_time);
}
writeTxt();
};
var MobileTelCompose = {
name: 'MobileTelCompose',
template: '#tpl-mobile-tel-compose',
props: {
numero: { type: String, default: '00 00 00 00 00' },
autocomplete: Array,
writespeed: { type: Number, default: 200 },
ontouch: { type: Boolean }
},
data: function () {
return {
autocomplete_selected: null,
numok: false,
disable: false
};
},
computed : {
},
mounted: function () {
this.numok = false;
},
methods: {
numerote: function () {
console.log(this.numero);
var that = this;
if (!this.disable || this.ontouch) {
this.disable = true;
that.numok = false;
var elem = document.getElementById('numinput');
if (!this.ontouch) { elem.value = ''; }
var cnum = that.numero.replace(/ /g, '');
writeTxtAnimInputCompose(this.numero, 'numinput', function () {
elem.scrollLeft = elem.scrollWidth;
that.numok = true;
for (var i = 0; i < that.autocomplete.length; i++) {
var n = that.autocomplete[i].number || '';
n = n.replace(/ /g, '');
if (n == cnum) {
that.autocomplete_selected = that.autocomplete[i];
break;
}
}
}, function (txtindex) {
that.numok = true;
var currentnum = that.numero.slice(0, txtindex).replace(/ /g, '');
if (that.autocomplete && that.autocomplete.length) {
}
}, that.writespeed, that.ontouch);
}
},
call: function () {
var that = this;
if (this.numok) {
this.$emit('setscreen', 'tel', this.ontouch ? 1 : 600, {tel: {name:this.numero}}, function () {
this.disable = false;
});
}
},
stopPropagation: function (e) {
e.stopPropagation();
}
}
};
var MobileTelDir = {
name: 'MobileTelDir',
template: '#tpl-mobile-tel-dir',
props: {
directory: {type: Array, default: function () { return [] }},
favoris: {type: Array, default: function () { return [] }},
history: {type: Array, default: function () { return [] }},
details: {type: Object},
nextscreen: {type: String}
},
data: function () { return {
entries: [],
selected: [],
fentries: [],
fselected: [],
hentries: [],
hselected: [],
historypage: false
}; },
computed : {
},
created: function () {
this.historypage = !!this.history && this.history.length;
},
mounted: function () {
this.selected = [];
this.entries = [];
for (var i = 0; i < this.directory.length; i++) {
this.selected.push(false);
this.entries.push(this.directory[i]);
}
this.fselected = [];
this.fentries = [];
for (var i = 0; i < this.favoris.length; i++) {
this.fselected.push(false);
this.fentries.push(this.favoris[i]);
}
this.hselected = [];
this.hentries = [];
for (var i = 0; i < this.history.length; i++) {
this.hselected.push(false);
this.hentries.push(this.history[i]);
}
},
methods: {
stopPropagation: function (e) {
e.stopPropagation();
},
showCompose: function () {
this.$emit('setscreen', 'telcompose', 600, {tel: this.tel_details});
},
selectEntry: function (i) {
Vue.set(this.selected, i, !this.selected[i]);
this.tel_details = this.entries[i];
this.tel_details.outmode = true;
if (this.details && this.details.enabled) {
this.$emit('setscreen', 'telcontact', 600, {tel: this.tel_details});
} else {
this.$emit('setscreen', 'tel', 600, {tel: this.tel_details});
}
},
selectFEntry: function (i) {
Vue.set(this.fselected, i, !this.fselected[i]);
this.tel_details = this.fentries[i];
this.tel_details.outmode = true;
if (this.details && this.details.enabled) {
this.$emit('setscreen', 'telcontact', 600, {tel: this.tel_details});
} else {
this.$emit('setscreen', 'tel', 600, {tel: this.tel_details});
}
},
selectHEntry: function (i) {
this.tel_details = this.hentries[i];
this.tel_details.outmode = true;
Vue.set(this.fselected, i, !this.fselected[i]);
this.$emit('setscreen', 'tel', 600, {tel: this.tel_details});
}
}
};
window.cc_data = window.cc_data || {};
var modemap = {
"Accueil/Verrouillage/Heure": 'DESKTOP',
"Appel Entrant": 'TELIN',
"Appel Sortant Numerote": 'TELOUTNUM',
"Appel Sortant Multiple": 'TELOUTMULTIPLE',
"SMS Details": "SMS",
"SMS Conversations": "SMSDIR",
"Repondeur": "REPONDEURLIST",
"APP": "APP",
"IMGS": "IMGS",
"SMSAPP": "SMSAPP",
"SMSCALL": "SMSCALL",
"TELINAPP": "TELINAPP",
};
var App = {
name: 'App',
template: '#tpl-app',
components: {
MobileMain: MobileMain,
MobileLock: MobileLock,
MobileTel: MobileTel,
MobileSms: MobileSms,
MobileTelDir: MobileTelDir,
MobileTelCompose: MobileTelCompose,
MobileSmsDir: MobileSmsDir,
MobileTelContact: MobileTelContact,
MobileFullPageImg: MobileFullPageImg,
MobileRepondeurList: MobileRepondeurList,
MobileScrollImg: MobileScrollImg
},
data: function () {
return {
cc_data: window.cc_data,
cscreen: 'lock',
disablenext: false,
timermark: false,
mode: '',
setscreen_timeout: null,
help: false,
topblack: false,
lock: {},
delay: cc_data.home.delay || cc_data.incall.delay,
main: window.cc_data.home || {},
disablenotif: false,
tel: Object.assign({}, window.cc_data.incall || {}),
teldir: cc_data.outcall || {},
sms: window.cc_data.sms || {},
smsdir: window.cc_data.smsdir || {},
repondeurlist: window.cc_data.repondeurlist || {},
imgs: window.cc_data.imgs || {},
app: window.cc_data.app || {},
keyscreenmap: {
'o': { sc: 'lock', desc: 'Off'},
't': { sc: 'tel', desc: 'Appel entrant', init:function (that) { that.tel.outmode = false;
that.tel.name = that.cc_data.incall.name;
that.tel.avatar = that.cc_data.incall.avatar;
that.tel.avatar_bg = that.cc_data.incall.avatar_bg;
}, ref:'tel', method:'init'},
'f': { sc: 'tel', desc: 'Appel entrant (2)', init:function (that) { that.tel.outmode = false;
that.tel.name = that.cc_data.incall.name2;
that.tel.avatar = that.cc_data.incall.avatar2;
that.tel.avatar_bg = that.cc_data.incall.avatar_bg2;
}, ref:'tel', method:'init'},
'a': { sc: 'tel', desc: 'Décroche', ref:'tel', method:'nextPhoneStatut'},
"z": { sc: 'tel', desc: 'Appel manqué', ref:'tel', method:'doMissedCall'},
'd': { sc: 'tel', desc: 'Double Appel', ref:'tel', method:'showDoubleCall'},
'n': { sc: 'main', ref:'main', method:'showNotif', desc: 'Afficher Notification'},
'c': { sc: 'main', ref:'main', method:'hideLastNotif', desc: 'Cacher derniere Notification'},
'r': { sc: 'sms', desc: 'Marquer LU', ref:'sms', method: 'markAsRead'},
'p': { sc: 'sms', desc: 'SMS msg precedent', ref:'sms', method: 'previousMsg'},
's': { sc: 'sms', desc: 'SMS suivant', ref:'sms', method: 'receiveMsg'},
'e': { sc: 'sms', desc: 'Effacer dernier MSG', ref:'sms', method: 'clearLastMsg'},
'm': { sc: 'smsdir', desc: 'Liste des Messages'},
'w': { sc: 'sms', desc: 'ecrit SMS', ref:'sms', method: 'writeTxt'},
'x': { sc: 'sms', desc: 'envoi SMS', ref:'sms', method: 'sendMsg'},
'y': { sc: 'app', desc: 'App'},
'b': { sc: 'app', desc: 'App NextImg', ref:'app', method: 'nextimg'},
'i': { sc: 'imgs', desc: 'Images'},
'h': { desc: 'Aide (ce menu)' },
'!': { desc: 'ecran noir au dessus' }
}
};
},
created: function () {
console.log(cc_data.mode);
this.mode = modemap[cc_data.mode] || cc_data.mode;
switch(this.mode) {
case 'TELIN' :
this.lock.nextscreen = 'tel';
break;
case 'TELINAPP' :
this.lock.nextscreen = 'tel';
this.tel.nextscreen = 'app';
break;
case 'TELOUTNUM':
this.lock.nextscreen = 'main';
this.main.nextscreen = 'telcompose';
this.tel.outmode = true;
break;
case 'TELOUTMULTIPLE':
this.lock.nextscreen = 'main';
this.main.nextscreen = 'teldir';
this.tel.nextscreen = 'teldir';
this.tel.outmode = true;
break;
case 'SMSDIR':
this.lock.nextscreen = 'main';
this.main.nextscreen = 'smsdir';
this.sms.nextscreen = 'smsdir';
break;
case 'REPONDEURLIST':
this.lock.nextscreen = 'main';
this.main.nextscreen = 'repondeurlist';
break;
case 'DESKTOP':
this.lock.nextscreen = 'main';
break;
case 'APP':
this.lock.nextscreen = 'main';
this.main.nextscreen = 'app';
this.setScreen('lock');
break;
case 'SMSAPP':
this.sms.nextscreen = 'main';
this.setScreen('sms');
this.main.nextscreen = 'app';
break;
case 'SMSCALL':
this.sms.nextscreen = 'main';
this.sms.nextdata = { main: { nonotif: true, nextscreen: 'teldir' } };
this.lock.nextscreen = 'main';
this.setScreen('lock');
this.main.nextscreen = 'sms';
this.tel.outmode = true;
break;
case 'IMGS':
this.lock.nextscreen = 'imgs';
this.imgs.nextscreen = 'main';
this.setScreen('imgs');
break;
case 'SMS':
this.lock.nextscreen = 'main';
this.main.nextscreen = 'sms';
break;
default:
this.lock.nextscreen = 'main';
}
},
mounted: function () {
var that = this;
document.onkeydown = function(e) {
that.keyup(e);
}
},
methods: {
init: function () {
this.mode = modemap[cc_data.mode] || 'TELIN';
},
keyup: function (e) {
var char = e.key.toLowerCase();
var screen = this.keyscreenmap[char];
if (screen && screen.sc !== undefined) {
if (screen.init) {
screen.init(this);
}
this.setScreen(screen.sc, 0);
}
if (char == 'h') {
this.help = !this.help;
}
if (char == '!') {
this.topblack = !this.topblack;
} else {
this.topblack = false;
}
if (screen && screen.ref) {
if(this.$refs[screen.ref]) {
var m = this.$refs[screen.ref][screen.method]
if (m) { Vue.nextTick(function () { m(); }) }
}
}
},
setData: function (key, data) {
if (key && this[key] && typeof(this[key]) == 'object') {
this[key] = Object.assign(this[key], data);
} else if (key && data) {
this[key] = data;
}
},
setScreen: function (name, next_timeout, data, cb, replace, settimermark) {
next_timeout = next_timeout || 0;
this.topblack = false;
console.log(replace, this.disablenext, name);
if (replace || (!this.disablenext && name)) {
this.disablenext = true;
this.timermark = settimermark;
var that = this;
if (replace && that.setscreen_timeout) {
clearTimeout(that.setscreen_timeout);
}
that.setscreen_timeout = setTimeout(function () {
if (data) {
for (var k in data) {
console.log(k);
Object.assign(that[k], data[k]);
}
}
that.cscreen = name;
that.disablenext = false;
that.timermark = false;
that.setscreen_timeout = null;
if (that.cscreen == 'lock') {
that.init();
}
if (cb) { cb(); }
}, next_timeout);
}
},
}
};
var app = new Vue({
render: function (h) { return h(App) }
});
app.$mount('#app');
{
"type": "object",
"title": "Telephone",
"properties": {
"mode": { "title" : "MODE", "type": "string", "enum": ["Accueil/Verrouillage/Heure",
"Appel Entrant",
"Appel Sortant Numerote",
"Appel Sortant Multiple",
"Repondeur",
"SMS Details",
"SMS Conversations",
"APP",
"IMGS"
] },
"unlockpos": { "title" : "Zone de depart", "type": "string", "enum": ["TOPRIGHT", "TOPLEFT", "BOTTOMRIGHT", "BOTTOMLEFT" ]},
"home": {
"type":"object",
"title":"Page Accueil",
"options": {
"collapsed": true
},
"properties": {
"background": { "title" : "fond d'ecran", "type": "string", "enum": ["#files"],
"links": [
{
"href": "#ROOT/files/{{self}}",
"mediaType": "image/png"
}]
},
"icons": { "type": "array",
"title": "Icons",
"format": "tabs",
"items":
{ "title" : "icon", "type": "string", "enum": ["#files"],
"links": [{
"href": "#ROOT/libs/{{self}}",
"mediaType": "image/png"
}] }
},
"delay": { "title" : "Delai avant allumage (sec)", "type": "number"},
"notifdelay": { "title" : "Delai avant apparition notification (sec)", "type": "number"},
"maxnotifs": { "title" : "Nombre max de notifications affichées", "type": "number", "default": 3},
"notifs": { "type": "array",
"title": "Notifications",
"format": "tabs",
"items": {
"type": "object",
"title": "Notification",
"properties": {
"author": { "type": "string", "title": "expediteur"},
"txt": { "type": "string", "title": "text"},
"mms": { "title" : "MMS", "type": "string", "enum": ["#files"],
"links": [
{
"href": "#ROOT/files/{{self}}",
"mediaType": "image/png"
}] },
"oico": { "title" : "Autre icone", "type": "string", "enum": ["#files"] },
"title": { "title" : "titre", "type": "string"},
"nextdelay": { "title" : "notif suivante (sec)", "type": "number" },
"fullimg": { "title" : "Image plein format", "type": "string", "enum": ["#files"],
"links": [
{
"href": "#ROOT/files/{{self}}",
"mediaType": "image/*"
}] }
}
}
},
"hour": { "type": "string", "title": "Heure plein ecran" },
"date": { "type": "string", "title": "Date plein ecran" },
"unlock": {"type": "boolean", "title":"Avec deverouillage", "format":"checkbox"}
}
},
"incall": {
"type":"object",
"options": {
"collapsed": true
},
"title":"Appel Entrant",
"properties": {
"name": { "title" : "Nom du correspondant", "type": "string"},
"name2": { "title" : "Nom du correspondant 2", "type": "string"},
"dcall": { "title" : "Nom du double appel", "type": "string"},
"avatar": { "title" : "Avatar rond", "type": "string", "enum": ["#files"],
"links": [
{
"href": "#ROOT/files/{{self}}",
"mediaType": "image/png"
}] },
"avatar_bg": { "title" : "Avatar Plein ecran", "type": "string", "enum": ["#files"],
"links": [
{
"href": "#ROOT/files/{{self}}",
"mediaType": "image/png"
}] },
"force_avatar_bg": {"title": "Avatar plein ecran pdt appel", "type":"boolean", "format": "checkbox"},
"delay": { "title" : "Delai avant appel (sec)", "type": "number"},
"misscalldelay": { "title" : "Delai avant fin d'appel (sec)", "type": "number"},
"offdelay": { "title" : "Delai avant ecran noir (sec)", "type": "number"},
"bt": {"title": "icone bluetooth activé", "type":"boolean", "format": "checkbox"}
}
},
"outcall": {
"type":"object",
"options": {
"collapsed": true
},
"title":"Appel sortant",
"properties": {
"numero": { "type": "string", "title": "numero à taper"},
"autocomplete": { "type": "array",
"title": "Recherche de numero",
"format": "tabs",
"items": {
"type": "object",
"title": "vcard",
"properties": {
"name": { "title" : "Nom", "type": "string"},
"number": { "title" : "Numero", "type": "string"}
}
}
},
"writespeed" : { "type": "number", "title": "temps d'ecriture entre 50 et 300 (ms)"} ,
"favoris": { "type": "array",
"title": "Favoris",
"format": "tabs",
"items": {
"type": "object",
"title": "vcard",
"properties": {
"avatar": { "title" : "Avatar", "type": "string", "enum": ["#files"],
"links": [
{
"href": "#ROOT/files/{{self}}",
"mediaType": "image/png"
}] },
"name": { "title" : "Nom", "type": "string"}
}
}
},
"directory": { "type": "array",
"title": "Repertoire téléphonique",
"format": "tabs",
"items": {
"type": "object",
"title": "vcard",
"properties": {
"avatar": { "title" : "Avatar", "type": "string", "enum": ["#files"],
"links": [
{
"href": "#ROOT/files/{{self}}",
"mediaType": "image/png"
}] },
"name": { "title" : "Nom", "type": "string"}
}
}
},
"history": { "type": "array",
"title": "Historique des appels",
"format": "tabs",
"items": {
"type": "object",
"title": "vcard",
"properties": {
"avatar": { "title" : "Avatar", "type": "string", "enum": ["#files"],
"links": [
{
"href": "#ROOT/files/{{self}}",
"mediaType": "image/png"
}] },
"name": { "title" : "Nom", "type": "string"},
"hdetails": {"title": "detail de l'appel", "type": "string"}
}
}
},
"details": { "type": "object",
"title": "Fiche contact",
"properties": {
"enabled": { "title": "fiche activé", "type": "boolean", "format": "checkbox", "default": false},
"numtel": { "title" : "Numero de tel", "type": "string"}
}
}
}
},
"sms": {
"type":"object",
"options": {
"collapsed": true
},
"title":"Conversation SMS Details",
"properties": {
"dest": { "title" : "correspondant", "type": "string"},
"color1": { "title": "couleur fond moi", "type": "string", "format": "color"},
"color2": { "title": "couleur text moi", "type": "string", "format": "color"},
"color3": { "title": "couleur pastille", "type": "string", "format": "color"},
"msgs": { "type": "array",
"title": "Messages précédents",
"format": "tabs",
"items": {
"type": "object",
"title": "Message",
"properties": {
"date": { "type": "string", "title": "date (ex: Aujourd'hui"},
"hour": { "type": "string", "title": "heure (ex: il y a 1 heure)"},
"txt": { "type": "string", "title": "texte du message"},
"mms": { "title" : "MMS", "type": "string", "enum": ["#files"],
"links": [
{
"href": "#ROOT/files/{{self}}",
"mediaType": "image/png"
}]
},
"dest": { "type": "boolean", "format": "checkbox", "title": "Message Reçu"},
"deletable": { "type": "boolean", "format": "checkbox", "title": "Supprimable"},
"wave": { "type": "boolean", "format": "checkbox", "title": "Wave"},
"readmark": { "type": "string", "title": "Lu/Non Lu", "enum": ["", "lu", "nonlu"]}
}
}
},
"writespeed" : { "type": "number", "title": "temps d'ecriture entre 50 et 300 (ms)"},
"vocal": { "type": "boolean", "format": "checkbox", "title": "micro dictee vocale"},
"dots": { "type": "boolean", "format": "checkbox", "title": "animation 3 petits points"},
"send_msgs": {
"type": "array",
"title": "Messages interactifs",
"format": "tabs",
"items": {
"type": "object",
"title": "Message interactif",
"properties": {
"date": { "type": "string", "title": "date (ex: il y a 1 heure)"},
"hour": { "type": "string", "title": "heure "},
"txt": { "type": "string", "title": "texte du message"},
"mms": { "title" : "MMS", "type": "string", "enum": ["#files"],
"links": [
{
"href": "#ROOT/files/{{self}}",
"mediaType": "image/png"
}]
},
"dest": { "type": "boolean", "format": "checkbox", "title": "Message Reçu"},
"deletable": { "type": "boolean", "format": "checkbox", "title": "Supprimable"},
"wave": { "type": "boolean", "format": "checkbox", "title": "Wave"},
"readmark": { "type": "string", "title": "Lu/Non Lu", "enum": ["", "lu", "nonlu"]}
}
}
},
"calling": { "title": "Icone Appel en cours", "type": "boolean", "format": "checkbox", "default": false},
"callbut": { "title": "Icone Appel sortant", "type": "boolean", "format": "checkbox", "default": false}
}
},
"smsdir": {
"type":"object",
"options": {
"collapsed": true
},
"title":"Conversations SMS",
"properties": {
"directory": {
"type": "array",
"title": "Liste des conversations",
"format": "tabs",
"items": {
"type": "object",
"title": "Conversation",
"properties": {
"name": { "title" : "Nom", "type": "string"},
"text": { "title" : "Texte", "type": "string"},
"date": { "title" : "Date", "type": "string"},
"letter": { "title" : "Lettre", "type": "string"},
"color": { "title" : "Couleur", "type": "string", "format": "color"},
"avatar": { "title" : "Avatar", "type": "string", "enum": ["#files"],
"links": [
{
"href": "#ROOT/files/{{self}}",
"mediaType": "image/png"
}] }
}
}
}
}
},
"repondeurlist": {
"type":"object",
"options": {
"collapsed": true
},
"title":"Messages répondeur",
"properties": {
"directory": {
"type": "array",
"title": "Liste des messages vocaux",
"format": "tabs",
"items": {
"type": "object",
"title": "Message vocal",
"properties": {
"name": { "title" : "Nom", "type": "string"},
"text": { "title" : "Texte", "type": "string"}
}
}
}
}
},
"app": {
"type":"object",
"options": {
"collapsed": true
},
"title":"App",
"properties": {
"title": { "title" : "Titre", "type": "string"},
"scroll": { "title" : "scroll", "type": "boolean", "format":"checkbox"},
"loop": { "title" : "loop", "type": "boolean", "format":"checkbox"},
"head": { "title" : "head", "type": "boolean", "format":"checkbox"},
"cam": { "title" : "cam", "type": "boolean", "format":"checkbox"},
"topimg": { "title" : "Top Image", "type": "string", "enum": ["#files"],
"links": [
{
"href": "#ROOT/files/{{self}}",
"mediaType": "image/png"
}]
},
"imgs": { "type": "array",
"title": "Imgs",
"format": "tabs",
"items":
{ "title" : "img", "type": "string", "enum": ["#files"],
"links": [{
"href": "#ROOT/libs/{{self}}",
"mediaType": "image/*"
}] }
}
}
},
"imgs": {
"type":"object",
"options": {
"collapsed": true
},
"title":"Imgs",
"properties": {
"imgs": { "type": "array",
"title": "Imgs",
"format": "tabs",
"items":
{ "title" : "img", "type": "string", "enum": ["#files"],
"links": [{
"href": "#ROOT/libs/{{self}}",
"mediaType": "image/*"
}] }
}
}
}
}
}
body, #app { user-select: none; }
/* ========== App.vue styles ========== */
.help {
position: absolute;
width: 80%;
left: 10%;
top: 10%;
border-radius: 3vw;
background: #F0F0F0F0;
padding: 5%;
z-index: 10000000000000000000;
font-size: 0.9em;
}
html, body {
font-family: "Roboto", Helvetica Neue, Helvetica, Arial, sans-serif;
background-color: black;
margin: 0;
padding: 0;
height: 100%;
overflow: hidden;
}
.vvfast {
animation-duration: 0.1s;
}
.fullw {
width: 100%;
}
.fullh {
height: 100%;
}
.abstop {
position: absolute;
top: 0;
left: 0;
}
.absbottom {
position: absolute;
bottom: 0;
left: 0;
}
.ztop {
z-index: 100;
}
.fade-enter-active, .fade-leave-active {
transition: opacity 0.5s ease;
}
.fade-enter, .fade-leave-to {
opacity: 0;
}
.timermark {
position: fixed;
z-index: 9900000000000000000000;
background-color: #333333;
width: 13px;
height: 13px;
bottom: 0;
right: 0;
}
/* ========== MobileLock styles ========== */
.black-screen {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100vh;
margin: 0;
background-color: black;
z-index: 100000;
}
.unlock-zone {
position: absolute;
width: 33vw;
height: 33vw;
margin: 0;
background-color: black;
z-index: 100001;
}
.unlock-zone.top-right {
top: 0;
right: 0;
}
.unlock-zone.top-left {
top: 0;
left: 0;
}
.unlock-zone.bottom-right {
bottom: 0;
right: 0;
}
.unlock-zone.bottom-left {
bottom: 0;
left: 0;
}
/* ========== MobileMain styles ========== */
.destround2 {
margin: auto;
border-radius: 50%;
background-color: #68BFD0;
color: #FFFFFF;
font-size: 1.2em;
width: 12vw;
line-height: 12vw;
margin-top: 5px;
margin-bottom: 5px;
display:inline-block;
text-align: center;
}
.icoround {
width: 12vw;
height: 12vw;
border-radius: 50%;
margin: auto;
line-height: 12vw;
margin-top: 5px;
margin-bottom: 5px;
}
.vfast { animation-duration: 0.2s; }
.icons-container {
margin-left: 4%;
margin-right: 4%;
position: absolute; bottom: 15vw; left: 0; width: 92%;
}
.icon {
padding-bottom: 5vw;
}
.tt td {
height: 20vw;
width: 20vw;
position: relative;
user-select:none
}
.tt td small{
font-size: 0.3em;
display: block;
user-select:none
}
.tt td .pulse {
width: 80px;
height: 80px;
background: #33333366;
border-radius: 40px;
animation: flashs 0.5s;
}
.linear-wipe {
background: linear-gradient(to right, #FFF 20%, #555 40%, #333 60%, #FFF 80%);
background-size: 200% auto;
color: #000;
background-clip: text;
text-fill-color: transparent;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
animation: shine 2s linear infinite;
}
@keyframes shine {
to {
background-position: 200% center;
}
}
@keyframes shake {
0%, 100% { transform: translateX(0); }
10%, 30%, 50%, 70%, 90% { transform: translateX(-10px); }
20%, 40%, 60%, 80% { transform: translateX(10px); }
}
.shake {
animation: shake 0.5s;
}
.transparent {
background-color: #00000000;
}
.main .time {
position: absolute;
top: 30%;
text-align: center;
margin:auto;
width: 100%;
font-size: 25vw;
color: #FFFFFF;
}
.main .unlock-legend {
position: absolute;
bottom: 10%;
text-align: center;
margin:auto;
width: 100%;
font-size: 4vw;
color: #FFFFFF;
}
.main .opac {
z-index: 10;
position: absolute;
width:100%;
top: 0;
left:0;
background: rgba(0,0,0, 0.7);
height: 100%;
-webkit-transition: opacity 0.7s ease-in-out;
-moz-transition: opacity 0.7s ease-in-out;
-o-transition: opacity 0.7s ease-in-out;
transition: opacity 0.7s ease-in-out;
}
.main .notifications .vvcenter {
display: inline-block;
vertical-align: middle;
float: none;
}
.main .notifications {
width: 90%;
position: relative;
top : 5vh;
margin: auto;
z-index: 20;
color: #303030;
}
.main .notification .numtel {
font-size: 1.0em;
display: inline-block;
}
.main .notification .notifdate {
font-size: 0.7em;
font-weight: 200;
}
.main .notifications .notification {
position: relative;
padding: 4%;
padding-left: 6%;
padding-right: 6%;
font-size: 5.2vw;
background: #FFFFFFBB;
color: #333;
border-radius: 4vw;
border-color: #555555;
border-width: 0px !important;
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
}
/* ========== MobileTel styles ========== */
.dcallbut {
display: inline-block;
font-size: 0.7em;
padding: 3vw;
margin: 3vw;
color: white;
border-radius: 5vw;
}
.doublecall {
padding: 3vw;
font-size: 5vw;
position: absolute;
width: 80%;
left: 10%; top: 5%;
border-radius: 5vw;
background: #F0F0F0;
color: black;
}
.buttonlegend {
font-size: 0.5em;
color: #888;
text-align: center;
}
.blink_me {
animation: blinker 1s linear infinite;
}
@keyframes blinker {
50% {
opacity: 0;
}
}
.statut.blink_me {
font-weight: bold;
font-size: 0.9em
}
.statut.warning {
color: red !important;
}
.text-center {
text-align: center;
}
.blue { color: #3980fa !important; }
.btnselect {
color: #276d20;
}
.ripple:after {
content: '';
position: absolute;
top: 4vw;
left: 6vw;
width: 15vw;
height: 15vw;
background: rgba(255, 255, 255, .2);
opacity: 0;
border-radius: 50%;
transform: scale(1, 1) translate(-50%);
transform-origin: 50% 50%;
}
@keyframes ripple {
0% {
transform: scale(0, 0);
opacity: 1;
}
20% {
transform: scale(2, 2);
opacity: 1;
}
100% {
opacity: 0;
transform: scale(4, 4);
}
}
.ripple::after {
animation: ripple 1s ease-out infinite;
}
.phone {
display: flex;
flex-direction: column;
align-items: stretch;
justify-content: space-around;
color: #F0F0F0;
font-size: 8vw;
background-size: cover;
background-position: center center;
}
.phone .item {
margin: auto;
margin-bottom: 5px;
}
.phone .photo {
color: #666;
font-size: 14vw;
padding-top: 5vw;
}
.phone .avatar {
width: 38%;
}
.phone .avatar.big {
width: 40%;
}
.phone .head {
width: 100%;
}
.phone .statut {
margin-top: 5vw;
font-size: 6vw;
color: #DDD;
text-align: center;
}
.phone .utils-buttons .fa-circle {
color: #333;
}
.phone .utils-buttons {
color: #999;
}
.phone .utils-buttons .selected {
color: #A0A0A0;
}
.phone .call-buttons {
font-size: 7.7vw;
padding-bottom: 12vw;
}
.phone .call-buttons .grey {
color: #666666;
}
.phone .call-buttons .greyw {
color: #999;
}
.phone .call-buttons .red {
color: red;
}
.phone .call-buttons .green {
color: green;
}
.phone .notifications .vvcenter {
display: inline-block;
vertical-align: middle;
float: none;
}
.phone .notifications {
z-index: 100000000000;
width: 90%;
position: absolute;
top : 5vh;
left: 5%;
margin: auto;
color: #303030;
}
.phone .notification .numtel {
font-size: 1.2em;
display: inline-block;
padding-bottom: 5px;
}
.phone .notification .notifdate {
font-size: 0.7em;
font-weight: 200;
}
.phone .notifications .notification {
padding: 7%;
padding-left: 10%;
padding-right: 10%;
font-size: 6vw;
background: #EDEDED;
border-radius: 4vw;
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
}
/* ========== MobileTelDir / MobileTelCompose / MobileTelContact / MobileRepondeurList styles ========== */
.avatarimg {
width: 12%; margin-left: 2%; margin-right: 3%
}
.user-dir {
padding-top: 6vw;
background-color: #F0F0F0;
height: 100%;
overflow: auto;
font-size: 5vw;
}
.list-group-item:first-child {
border-top-left-radius: .5rem !important;
border-top-right-radius: .5rem !important;
}
.list-group-item:last-child {
border-bottom-right-radius: .5rem !important;
border-bottom-left-radius: .5rem !important;
}
.user-dir .list-group {
margin-right: 7px;
margin-left: 7px;
border-radius: 20px;
}
.user-dir .list-group-item {
vertical-align: middle;
font-size: 0.8em;
padding: 1.8vh; padding-right: 1vw; padding-bottom: 1vh;
}
.user-dir .list-group-item.selected {
background-color: #C0C0C0;
}
.user-dir .win-head {
padding: 2%;
position: absolute;
left: 0;
top: 3.5vw;
width: 100%;
z-index: 99;
background-color: #F0F0F0;
box-shadow: 0px 3px 3px 0px #65656557;
}
.user-dir .win-head .title {
font-size: 1em;
}
.user-dir .win-content {
color: #666;
position: relative;
top: 28vw;
z-index: 10;
}
.user-dir .dirtitle {
color: #6fc16f;
text-transform: uppercase;
font-weight: bold;
padding-left: 5%;
padding-top: 8px;
padding-bottom: 8px;
font-size: 0.6em;
}
.user-dir .win-content .trash-but {
float: right;
}
.user-dir .win-content .phone-but {
float: right;
font-size: 1.2em
}
.user-dir .win-head .nav .title {
display: flex-item;
margin-right: 6vw;
font-size: 0.9em;
display: inline-block;
font-weight: normal;
vertical-align: top;
}
.user-dir .win-head .nav .title.active {
color: #6fc16f;
border-radius: 10px;
text-decoration: underline;
font-weight: bold;
}
/* TelCompose specific */
.win-content .numkey {
width: 100%;
background: #FFF;
}
.win-content .numinput {
width: 100%;
height: 13vh;
font-size: 11vw;
font-weight: normal;
font-family: sans-serif;
padding-left: 5%;
background: #FFF;
}
/* TelContact specific */
.user-dir .win-content.telcontact-content {
color: #666;
position: relative;
z-index: 10;
background-color: #F0F0F0;
top: 0;
}
/* ========== MobileSMS styles ========== */
.playing {
background: rgba(255, 255, 255, 0.1);
width: 2rem;
height: 2rem;
border-radius: 0.3rem;
display: flex;
justify-content: space-between;
align-items: flex-end;
padding: 0.5rem;
box-sizing: border-box;
}
.playing__bar {
display: inline-block;
background: black;
width: 25%;
height: 100%;
animation: up-and-down 1.3s ease infinite alternate;
}
.playing__bar1 {
height: 60%;
}
.playing__bar2 {
height: 30%;
animation-delay: -2.2s;
}
.playing__bar3 {
height: 75%;
animation-delay: -3.7s;
}
@keyframes up-and-down {
10% { height: 30%; }
30% { height: 100%; }
60% { height: 50%; }
80% { height: 75%; }
100% { height: 60%; }
}
.animate__animated.fast {
animation-duration: 0.3s;
}
img.mms {
border-radius: 2vw;
}
.mmblock {
margin-bottom: 1.2vh
}
.mmblock.right {
text-align: right;
}
.win-head {
font-size: 5vw;
color: #333;
padding-left: 4vw;
padding-right: 4vw;
padding-top: 3vw;
padding-bottom: 3vw;
box-shadow: 0px 3px 3px 0px #65656557;
}
.destround {
text-align: center;
border-radius: 50%;
background-color: #878786;
color: #FFFFFF;
font-size: 7vw;
text-transform: capitalize;
width: 11vw;
line-height: 11vw;
margin: 6px;
margin-left: 8px
}
.sms .opac {
position: absolute;
z-index: 10000;
width:100%;
top: 0;
left:0;
background: rgba(0,0,0, 0.3);
height: 100%;
transition: opacity 0.7s ease-in-out;
}
.deletediag {
padding: 15px;
padding-left: 20px;
padding-right: 20px;
font-family: 'roboto';
margin-left: 10%;
top: 30vh; left: 0;
z-index: 9999999999999999999;
position: absolute;
width: 80%;
border-radius: 20px;
background: white;
}
.inputblock .txtinput {
overflow: hidden; resize:none; font-size: 1.0em;
}
@font-face {
font-family: emoji;
src: url('NotoColorEmoji.ttf') format('truetype');
unicode-range: U+1F300-1F5FF, U+1F600-1F64F, U+1F680-1F6FF, U+2600-26FF;
}
.sms {
font-family: emoji, "Roboto", Helvetica Neue, Helvetica, Arial, sans-serif;
line-height: 1;
background-color: white;
height: 100%;
font-size: 4.0vw;
display: flex;
flex-direction: column;
align-items: stretch;
justify-content: space-between;
}
.sms .win-footer {
width: 100%;
}
.sms .win-footer .inputblock {
padding-top: 2vw;
text-align: center;
margin-bottom: 1vw;
}
.sms .win-footer .inputblock .far {
color: grey;
}
.sms .keyboard img {
width: 100%;
}
.sms .win-footer textarea {
width: 100%;
height: auto;
vertical-align: bottom;
font-size: 1.1em;
padding: 8px;
box-shadow: none; outline: none;
background: white;
border: 0px solid #D0D0D0;
border-radius: 5vw;
}
.sms .win-footer .sendtxt{
border-radius: 5vw;
background: white;
border: 1px solid #D0D0D0;
padding-left: 5%;
padding-right: 5%;
}
.sms .win-content {
margin-bottom: auto;
margin-left: 0;
margin-right: 0;
color: #666;
z-index: 10;
text-align: left;
overflow: hidden;
overflow-y: auto;
}
.sms .message {
max-width: 62%;
vertical-align: middle;
margin: 1.5vw;
}
.vcenter {
display: inline-block;
vertical-align: middle;
float: none;
}
.msgdate {
text-align: center;
color: #808080;
font-size: 0.9em;
padding-top: 1vh;
padding-bottom: 1vh;
}
.msghour {
vertical-align: bottom;
color: #808080;
font-size: 0.7em;
position: relative;
top: -2vw;
}
.left .msghour {
margin-left: 2vw;
}
.right .msghour {
padding-right: 4vw;
}
.sms .message .message-box{
margin-top: 1.2vw;
margin-bottom: 1.2vw;
padding: 3.5vw;
background: #FFF;
border-radius: 4vw;
font-size: 1.2em;
line-height: 1.2;
position: relative;
width: auto;
transition: opacity 0.7s ease-in-out;
}
.sms .message.left .message-box {
margin-right: auto;
color: #3D3D41;
background-color: #F0F0F0;
}
.sms .message.right .message-box {
margin-left: auto;
color: white;
background-color: #00A192;
float: right;
}
.sms .message.left {
margin-left: 8vw;
}
.sms .message.right {
margin-left: auto;
margin-right: 8vw;
}
.sms .message small {
font-size: 0.5em;
}
.sms textarea.form-control:focus{
border-color: #A0A0A0;
-webkit-box-shadow: none;
box-shadow: none;
}
@keyframes animate {
0%, 40%, 100% {
opacity: 0.5;
}
20% {
opacity: 1;
}
}
.dot {
display: inline-block;
vertical-align: baseline;
animation-name: animate;
animation-duration: 1s;
animation-iteration-count: infinite;
animation-timing-function: ease;
animation-delay: .2s;
}
.dot:first-child {
animation-delay: 0s;
}
.dot:last-child {
animation-delay: .4s;
}
/* ========== MobileSMSDir styles ========== */
.win-head .search {
border-radius: 20px;
background: #E0E0E0;
margin-right: 3%;
margin-left: 3%;
width: 94%;
font-size: 5vw;
padding: 5px;
padding-right: 20px;
}
.sms-dir .list-group-item {
padding: 2vh;
vertical-align: middle;
font-size: 1.2em;
background: white;
border-right: none;
border-left: none;
border-width : 0vw;
border-radius: 4vw;
margin-bottom: 1vw;
}
.sms-dir .list-group {
background: white;
}
.sms-dir .list-group-item.selected {
background-color: #D0D0D0;
}
.sms-dir .contact_to_choose.clicked {
background-color: #C0C0C0;
}
.sms-dir .win-content {
color: #666;
position: relative;
z-index: 10;
font-size: 0.9em;
height: 80vh;
overflow: auto;
}
/* ========== MobileRepondeurList styles ========== */
.bars {
height: 25px;
margin-left: 10px;
margin-right: 10px;
position: relative;
width: 20px;
}
.bar {
background: #666;
bottom: 1px;
height: 3px;
position: absolute;
width: 3px;
animation: sound 0ms -800ms linear infinite alternate;
}
@keyframes sound {
0% {
opacity: .35;
height: 3px;
}
100% {
opacity: 1;
height: 23px;
}
}
.bar:nth-child(1) { left: 1px; animation-duration: 474ms; }
.bar:nth-child(2) { left: 5px; animation-duration: 433ms; }
.bar:nth-child(3) { left: 9px; animation-duration: 407ms; }
.bar:nth-child(4) { left: 13px; animation-duration: 458ms; }
.list-enter-active, .list-leave-active {
transition: all 0.4s;
}
.list-enter, .list-leave-to {
opacity: 0;
transform: translateX(30px);
}
/* ========== MobileFullPageImg styles ========== */
.fpageimg {
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
background: black;
}
/* ========== MobileScrollImg styles ========== */
.scrollimg-user-dir {
background-color: white;
height: 100%;
overflow: auto;
font-size: 5vw;
display: flex;
flex-direction: column;
}
.scrollimg-user-dir .win-headd {
color: #F0F0F0;
left: 0;
width: 100%;
z-index: 99;
}
.scrollimg-user-dir .win-headd div {
margin: 3vw;
padding: 2%;
}
.scrollimg-user-dir .win-headd .title {
font-size: 1.3em;
}
.scrollimg-user-dir .win-content {
color: #666;
position: relative;
height: 100%;
padding-bottom: 2%;
overflow: auto;
z-index: 10;
}
#video {
position: absolute;
top: 0; left: 0;
width: 100%;
height: 80vh;
background: black;
}
#startbutton {
user-select: none;
border-radius: 50%;
background: white;
border: #444 8px solid;
display: inline-block;
width: 50px;
height: 50px;
margin-left: 18%;
margin-right: 18%;
vertical-align: middle;
}
.scrollimg-icon {
vertical-align: middle;
display: inline-block;
}
.centerbot {
vertical-align: middle;
color: white;
left: 0;
position: absolute;
bottom: 19vh;
width: 100%;
text-align: center;
}
@keyframes flash {
50% {
opacity: 1;
}
}
#flash {
opacity: 0;
background: white;
position: absolute;
top: 0; left: 0;
animation-name: flash;
animation-duration: 0.3s;
width: 100%; height: 100vh;
}
/* ========== Config styles ========== */
.config {
background: white;
height: 100vh;
overflow:auto;
}
// Template loader: fetches external HTML template files and injects them as
// <script type="text/x-template"> elements, then loads component scripts.
(function () {
var templates = [
'tpl-app',
'tpl-mobile-lock',
'tpl-mobile-main',
'tpl-mobile-tel',
'tpl-mobile-tel-dir',
'tpl-mobile-tel-compose',
'tpl-mobile-tel-contact',
'tpl-mobile-sms',
'tpl-mobile-sms-dir',
'tpl-mobile-repondeur-list',
'tpl-mobile-full-page-img',
'tpl-mobile-scroll-img'
];
var componentScripts = [
'files/MobileLock.js',
'files/MobileMain.js',
'files/MobileTel.js',
'files/MobileTelDir.js',
'files/MobileTelCompose.js',
'files/MobileTelContact.js',
'files/MobileSMS.js',
'files/MobileSMSDir.js',
'files/MobileRepondeurList.js',
'files/MobileFullPageImg.js',
'files/MobileScrollImg.js',
'files/app.js'
];
var promises = templates.map(function (tplId) {
return fetch('files/' + tplId + '.html')
.then(function (res) { return res.text(); })
.then(function (html) {
var el = document.createElement('script');
el.type = 'text/x-template';
el.id = tplId;
el.innerHTML = html;
document.body.appendChild(el);
});
});
Promise.all(promises).then(function () {
loadScripts(componentScripts, 0);
});
function loadScripts(scripts, i) {
if (i >= scripts.length) return;
var s = document.createElement('script');
s.src = scripts[i];
s.onload = function () { loadScripts(scripts, i + 1); };
document.body.appendChild(s);
}
})();
<div id="approot" class="layout">
<mobile-lock v-if="topblack" key="topblack"></mobile-lock>
<transition name="fade">
<mobile-lock v-if="cscreen == 'lock'" v-on:setscreen="setScreen" v-bind:mode="mode"
v-bind="lock"
v-bind:unlockpos="cc_data.unlockpos"
v-bind:delay="delay * 1000" key="lock"></mobile-lock>
<mobile-main v-else-if="cscreen == 'main'" class="fullh fullw abstop"
v-on:setscreen="setScreen"
v-on:setdata="setData"
ref="main"
v-bind:mode="mode"
v-bind:disablenotif="disablenotif"
v-bind="main"
key="main"></mobile-main>
</transition>
<transition name="custom-classes-transition-bsounce"
enter-active-class="animate__animated vvfast animate__zoomIn"
leave-active-class="animate__animated vvfast animate__fadeOut" >
<mobile-full-page-img v-if="cscreen == 'imgs'" class="fullh fullw abstop" v-on:setscreen="setScreen"
ref="imgs"
v-bind="imgs"
key="imgs"></mobile-full-page-img>
<mobile-scroll-img v-if="cscreen == 'app'" class="fullh fullw abstop" v-on:setscreen="setScreen"
ref="app"
v-bind="app"
key="app"></mobile-scroll-img>
<mobile-tel v-else-if="cscreen == 'tel'" class="fullh fullw abstop" v-on:setscreen="setScreen" v-on:setdata="setData"
v-bind:mode="mode"
v-bind="tel"
ref="tel"
key="tel">
</mobile-tel>
<mobile-tel-dir v-else-if="cscreen == 'teldir'" class="fullh fullw abstop" v-on:setscreen="setScreen"
key="teldir"
v-bind:mode="mode"
v-bind="teldir"></mobile-tel-dir>
<mobile-tel-compose v-else-if="cscreen == 'telcompose'" class="fullh fullw abstop" v-on:setscreen="setScreen" key="telcompose"
v-bind:mode="mode"
v-bind="teldir"></mobile-tel-compose>
<mobile-tel-contact v-else-if="cscreen == 'telcontact'" class="fullh fullw abstop" v-on:setscreen="setScreen" key="telcontact"
v-bind:mode="mode"
v-bind="teldir.details"
v-bind:avatar="tel.avatar"
v-bind:name="tel.name"></mobile-tel-contact>
<mobile-sms-dir v-else-if="cscreen == 'smsdir'" class="fullh fullw abstop" v-on:setscreen="setScreen" key="smsdir"
v-bind:mode="mode"
v-bind="smsdir"></mobile-sms-dir>
<mobile-repondeur-list v-else-if="cscreen == 'repondeurlist'" class="fullh fullw abstop" v-on:setscreen="setScreen" key="repondeurlist"
v-bind:mode="mode"
v-bind="repondeurlist"></mobile-repondeur-list>
<mobile-sms v-else-if="cscreen == 'sms'" class="fullh fullw abstop" v-on:setscreen="setScreen" key="sms" v-on:setdata="setData"
ref="sms"
v-bind:mode="mode"
v-bind="sms"></mobile-sms>
</transition>
<div class="timermark" v-if="timermark"></div>
<div class="help" v-if="help">
<a class="float-right" href="#" @click="help=false"><i class="fa fa-times fa-lg"></i> </a>
<h5>Raccourcis</h5>
<ul>
<li v-for="(value, key) in keyscreenmap">
<b>{{ key }}</b> : {{ value.desc }}
</li>
</ul>
</div>
</div>
<div class="fpageimg">
<img class="head" src="libs/headwna.png" style="width: 100%; position: fixed; top: 0; left: 0; z-index: 10000; ">
<transition-group name="custom-classes-transition"
enter-active-class="animate__animated animate__fast animate__slideInRight"
leave-active-class="animate__animated animate__fast animate__slideOutLeft">
<div v-for="(img, i) in imgs" :key="'iiii' + i" style="width: 100vw; height: 100vh; background-size: contain; background-repeat: no-repeat; background-position: center center; position: absolute; top: 0; left: 0"
v-bind:style="{ 'background-image' : 'url(\'files/' + img + '\')'}" @click.stop="nextimg" v-if="index === i"></div>
</transition-group>
</div>
<div class="black-screen" v-on:click="stopPropagation" >
<div class="unlock-zone" v-bind:class="unlockClass" @click="$emit('setscreen', nextscreen, delay, {}, function() {}, false, true)">
</div>
</div>
<div class="main" @click="showNotif">
<img class="fullw fullh abstop" style="object-fit: cover" v-bind:src="'files/' + background" key="bg">
<img class="fullw abstop" src="libs/headwna.png">
<transition name="fade">
<div class="opac transparent" v-if="opac"></div>
</transition>
<transition name="fade">
<div v-if="(unlock && !locked) || (hour && !locked)" key="unl" @click.stop="locked=1" >
<div class="time" v-if="hour" style="z-index: 50">
{{hour}}
<div class="date" style="font-size: 0.2em">
{{date}}
</div>
</div>
<div class="unlock-legend linear-wipe" style="z-index: 50">
<img src="libs/glisser.png" style="width: 7vw; margin-right: 1em"> Glisser pour déverrouiller
</div>
<div class="time text-center" v-if="unlock && finger && !hour">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" version="1.1" style=" width: 20%; fill:#CCC; shape-rendering:geometricPrecision;text-rendering:geometricPrecision;image-rendering:optimizeQuality;" viewBox="0 0 4473 5591.25" x="0px" y="0px" fill-rule="evenodd" clip-rule="evenodd"><g><path class="fil0" d="M2237 0c617,0 1176,250 1581,655 405,405 655,964 655,1582 0,617 -250,1176 -655,1581 -405,405 -964,655 -1581,655 -618,0 -1177,-250 -1582,-655 -405,-405 -655,-964 -655,-1581 0,-618 250,-1177 655,-1582 405,-405 964,-655 1582,-655zm1449 787c-371,-371 -883,-600 -1449,-600 -567,0 -1079,229 -1450,600 -371,371 -600,883 -600,1450 0,566 229,1078 600,1449 371,371 883,601 1450,601 566,0 1078,-230 1449,-601 371,-371 601,-883 601,-1449 0,-567 -230,-1079 -601,-1450zm-2287 302c-46,22 -102,3 -125,-43 -23,-46 -4,-101 42,-124 307,-152 614,-225 922,-224 307,2 614,77 919,223 47,23 66,78 44,124 -22,47 -77,66 -124,44 -281,-134 -561,-204 -840,-205 -279,-1 -558,66 -838,205zm-378 763c-32,40 -91,46 -131,14 -40,-32 -46,-90 -14,-130 95,-119 200,-221 313,-307 313,-239 686,-358 1057,-357 371,2 740,124 1043,367 107,85 205,185 292,298 31,41 23,100 -18,131 -41,31 -99,23 -130,-18 -79,-102 -166,-191 -260,-266 -269,-216 -598,-325 -928,-326 -330,-1 -664,105 -943,319 -102,78 -197,170 -281,275zm299 1289c25,45 8,102 -37,126 -45,25 -101,8 -126,-37 -108,-198 -162,-392 -172,-575 -13,-240 49,-460 164,-646 113,-186 278,-338 470,-443 169,-93 361,-149 558,-160 229,-12 479,37 702,164 194,110 368,278 492,516 187,357 153,636 30,814 -61,88 -145,152 -236,187 -91,36 -191,44 -283,22 -157,-37 -290,-158 -327,-372 -31,-185 -148,-292 -275,-326 -55,-14 -112,-16 -164,-4 -49,11 -94,35 -130,70l-4 4c-71,76 -100,207 -36,394 56,162 138,305 254,426 117,122 270,225 469,305 47,19 70,74 51,121 -19,48 -74,71 -121,52 -223,-90 -397,-208 -533,-350 -137,-142 -232,-308 -296,-494 -91,-265 -38,-462 79,-584l5 -6c61,-60 138,-100 222,-119 81,-19 168,-17 252,5 191,51 365,208 411,476 22,128 97,200 186,221 55,14 115,8 173,-14 58,-23 111,-63 150,-120 88,-127 107,-338 -42,-622 -106,-203 -254,-347 -418,-440 -191,-109 -405,-151 -602,-140 -169,9 -333,57 -478,137 -164,90 -304,219 -401,376 -95,156 -147,340 -136,540 8,157 55,324 149,496zm1796 -544c6,51 -30,97 -81,104 -51,6 -97,-30 -104,-81 -41,-329 -256,-525 -504,-592 -157,-43 -326,-35 -474,23 -143,56 -266,161 -332,312 -120,272 -65,697 345,1276 30,41 20,99 -21,129 -42,30 -100,20 -130,-22 -455,-641 -508,-1132 -365,-1458 88,-200 248,-337 436,-411 184,-72 395,-82 590,-29 314,85 587,333 640,749zm-987 61c-6,-51 31,-97 82,-103 51,-6 97,31 103,82 26,225 104,393 240,500 138,109 341,158 612,144 52,-3 95,37 98,88 3,51 -37,95 -88,98 -319,17 -563,-47 -737,-184 -177,-139 -278,-349 -310,-625z"/></g></svg>
<div class="text-center" style="font-size: 0.5em"><i class="fa fa-lock"></i></div>
</div>
</div>
</transition>
<transition name="custom-classes-transition-bsounce"
enter-active-class="animate__animated vfast animate__slideInUp"
leave-active-class="animate__animated fast animate__fadeOut" >
<div class="fullw fullw abstop" v-if="unlock && locked == 1" key="unl" style="color: white">
<div class="text-center"
:class="{ 'shake': wrongCode }"
style="margin-left: 5%; margin-right: 5%; margin-top: 17vh; margin-bottom: 3vh; width: 90%; font-size: 8vw; border-radius:7vw; opacity: 0.8; background: rgba(23, 23, 23, 0.4)"><div><i class="fal fa-lock"></i></div>
{{code}} </div>
<table class="tt fullw text-center" style="padding: 10px; font-size: 10vw; user-select:none" @click.stop="addcode">
<tr><td>1<small> </small></td><td>2<small>ABC</small></td><td>3<small>DEF</small></td></tr>
<tr><td>4<small>GHI</small></td><td>5<small>JKL</small></td><td>6<small>MNO</small></td></tr>
<tr><td>7<small>PQRS</small></td><td>8<small>TUV</small></td><td>9<small>WXYZ</small></td></tr>
<tr><td><i class="fal fa-times"></i></td><td style="position: relative">0</td><td><i class="fal fa-check"></i></td></tr>
</table>
<div style="text-align: center; margin-top: 10vw">
<div style="display: inline-block; padding: 2vw; padding-left: 5vw; padding-right: 5vw; border-radius: 10vw; text-align: center; border: 1px solid white; background: #353D4B; color: white">Appel d'urgence</div>
</div>
</div>
</transition>
<transition name="fade">
<div v-if="(!unlock && !hour) || locked > 1 || (hour && !unlock && locked == 1)" key="locs">
<img v-if="(icons2 && icons2.length) || (nnotifs && nnotifs.length)" class="fullw absbottom" src="libs/iconsbot.png">
<img v-else class="fullw absbottom" src="libs/icons.png">
<div class="icons-container">
<div class="row mb-2">
<div class="col-3 mb-3" v-for="i in icons2">
<img :src="'files/' + i" class="icon img-fluid">
</div>
</div>
<div class="text-center mb-3" style="color: white; font-size: 2vw"><i class="fas fa-circle mr-1"></i><i class="far fa-circle mr-1"></i><i class="far fa-circle"></i> </div>
<div class="row">
<div class="col-3" v-for="i in icons">
<img :src="'files/' + i" class="icon img-fluid">
</div>
</div>
</div>
</div>
</transition>
<div class="notifications" style="top: 10vh" v-if="(!unlock || !locked)">
<div v-for="(notif, i) in nnotifs.slice().reverse()">
<transition name="custom-classes-transition-bounce"
enter-active-class="animate__animated vfast animate__slideInDown"
leave-active-class="animate__animated fast animate__fadeOut" >
<div v-if="notif.visible && notif.fullimg" class="panel panel-default notification mt-2" :key="'notif' + i"
style="padding: 0; overflow: hidden">
<img :src="'files/' + notif.fullimg" class="img img-fluid fullw" style="display: block">
</div>
<div v-else-if="notif.visible" class="panel panel-default notification mt-2" :key="'notif' + i">
<i class="fal fa-times float-right" style="font-size: 0.7em; color: #9D9D9C; position: absolute; right: 4vw; top: 2vw" @click.stop="hideNotif(i)"></i>
<div style="font-weight: bold; margin-bottom: 10px;font-size: 0.7em">
<i class="fas fa-comment-alt mr-2"></i> <span class=""> {{notif.title || 'Mess.'}} <i><small class="text-muted">{{notif.time || 'Maintenant'}}</small></i> </span> <i class="ml-2 fal fa-chevron-down"></i>
</div>
<div class="row" style="margin-bottom: 15px;">
<div class="d-inline-block text-center" style="width: 20%">
<img v-if="notif.oico" :src="'files/' + notif.oico" class="icoround">
<span v-else class="destround2" :style="{'background-color': notif.color}"><span>{{notif.author[0]}}</span></span>
</div><div class="d-inline-block pr-1" style="width: 80%">
<div><span class="numtels"><strong>{{notif.author}}</strong></span></div>
<div>{{notif.txt}}</div>
</div>
</div>
<div class="row" v-if="notif.mms" >
<br>
<div class="col">
<img v-bind:src="'files/' + notif.mms"
class="img img-fluid rounded fullw" style="margin: 0;"
@click.stop="showMMS(notif.mms)">
</div>
</div>
</div>
</transition>
</div>
</div>
</div>
<div>
<img class="fullw abstop ztop" src="libs/headbna.png" style="background: #F0F0F0">
<div class="user-dir">
<div class="win-head">
<div class="title" style="width: 100%">
<div style="display: inline-block; width: 72%; margin:0; padding: 3vw">
<span class="fal fa-arrow-left"></span> <span class="ml-3"> Messages Vocaux</span>
</div><div style="display: inline-block; width: 28%; text-align: right">
<i class="fal fa-voicemail mr-3"></i>
</div>
</div>
</div>
<div class="win-content">
<div>
<div class="dirtitle">Répondeur</div>
<transition-group name="list-complete" tag="ul" class="list-group">
<li class="list-group-item list-complete-item" v-for="(entry, i) in entries" v-bind:key="'entry2' + i"
@click="playEntry(i);" v-bind:class="{selected : selected[i]}">
<div>
<span class="fa-stack" v-if="!entry.avatar" style="font-size: 5.6vw">
<i class="fas fa-circle fa-stack-2x" style="color: #999"></i>
<i class="fal fa-voicemail fa-stack-1x" style="color: white"></i>
</span>
<span style="display:inline-block; vertical-align:middle; padding-left: 3%; color:#9D9D9C; line-height: 0.98em;">
<b>{{entry.name}}</b><br>
<span style="color: black; font-size: 0.9em; "> <small>{{entry.text}}</small></span></span>
<span class="float-right" style="text-align: right; padding-top: 8px; padding-right: 8px;">
<span v-if="selected[i]">
<i class="fal fa-lg fa-pause"></i>
{{counter}}
<span v-if="selected[i]" class="d-inline-block">
<div class="bars"><div class="bar"></div><div class="bar"></div><div class="bar"></div><div class="bar"></div></div>
</span>
</span>
<i v-else class="fal fa-lg fa-play"></i>
</span>
</div>
<div class="row" style="font-size: 0.8em; margin-top: 9px;">
<div class="col-1"></div>
<div class="col-4 text-center" @click.stop="openTel(entry.name)" style="color: green; padding-left: 3vw"> <i class="fal fa-phone"></i> Appeler</div>
<div class="col-3 text-center"><i v-if="selected[i]" class="fal fa-lg fa-volume-up"></i></div>
<div @click.stop="opac = true; deletediag = true; todelete=i" class="col-4 text-center" style="color: red"><i class="fal fa-trash"></i> Effacer </div>
</div>
</li>
</transition-group>
</div>
</div>
</div>
<img src="libs/iconsbot.png" style="position: absolute; bottom: 0; left: 0; width: 100%; filter: invert(1)">
<transition name="fade">
<div class="opac" v-if="opac"></div>
</transition>
<transition name="fade">
<div v-if="deletediag" class="deletediag">
<h4 style="line-height: 1.6em"> Supprimer le message ? </h4>
<h4><b><a href="#"
@click.stop="opac=false; deletediag=false; deletemsg()">
<span class="fa fa-trash"></span> Supprimer</a> <a href="#">Annuler</a></b></h4>
</div>
</transition>
</div>
<div class="sms-dir abstop fullw fullh" style="background: white; overflow: hidden; user-select: none">
<img class="fullw ztop" src="libs/headbna.png">
<div class="win-head">
<div class="row">
<div class="col-8"><i class="fal fa-comment-alt-lines"></i> <span class="pl-2">MESSAGES</span></div>
<div class="col-4 text-right"><i class="fas fa-ellipsis-v"></i></div>
</div>
<div class="search text-right mt-2"><span class="text-muted"></span> <i class="fas fa-search"></i></div>
</div>
<div class="win-content">
<transition-group name="list-complete" tag="ul" class="list-group">
<li class="list-group-item list-complete-item" v-for="(entry, i) in entries" v-bind:key="entry.name"
@click="selectEntry(i);" v-bind:class="{selected : selected[i]}">
<img v-if="entry.avatar" :src="'files/' + entry.avatar" class="destround2 fullw" style="background: white">
<span v-else class="destround2" :style="{'background-color': entry.color}">
<span v-if="entry.letter">{{entry.letter}}</span>
<i v-else class="fa fa-user"></i>
</span>
<span style="display:inline-block; vertical-align:middle; padding-left: 5%; color:black; font-size: 1.0em; line-height: 1.2em;"> {{entry.name}}<br>
<span style="color: #888888; font-size: 0.9em; "> <small>{{entry.text}}</small></span></span>
<span class="text-muted float-right" style="text-align: right; padding-top: 8px; padding-right: 8px; font-size: 0.7em">
{{entry.date}}</span>
</li>
</transition-group>
</div>
<img class="fullw absbottom" src="libs/iconsbot.png" style="filter: invert(1)">
</div>
<div @click="receiveMsg" class="sms abstop fullw fullh" style="overflow: hidden; user-select: none">
<transition name="fade">
<div class="opac" v-if="opac"></div>
</transition>
<transition name="fade">
<div @click.stop="opac=false; deletediag=false; hideAll()" v-if="deletediag" class="deletediag">
<h6 style="line-height: 1.6em" v-if="!deletesomemsg"> Supprimer la conversation ? </h6>
<h6 style="line-height: 1.6em" v-if="deletesomemsg"> Supprimer les messages ? </h6>
<h6><a href="#"> <span class="fa fa-trash"></span> Supprimer Annuler</a></h6>
</div>
</transition>
<img class="fullw ztop head" src="libs/headbna.png">
<div class="win-head">
<div class="row" @click.stop="openTel">
<div class="col-8"><i class="fal fa-arrow-left"></i> <span class="ml-2">{{dest}}</span></div>
<div class="col-4 text-right">
<template v-if="hasselection">
<i class="fal fa-trash mr-3" @click.stop="showDeleteDiag(msg, $event)"> </i>
<i class="fas fa-ellipsis-v" @click.stop="showDeleteDiag(msg, $event)"></i>
</template>
<template v-else >
<i class="fal fa-phone mr-3"></i><i class="fal fa-video mr-3"></i>
<i class="fas fa-ellipsis-v"></i>
</template>
</div>
</div>
</div>
<div class="win-content" id="wcontent">
<div v-if="!msgs_data.length"><br><br><h5 class="text-center">Aucun message</h5></div>
<div class="messages">
<br>
<transition-group name="custom-classes-transition-zoom2"
enter-active-class="animate__animated fast animate__zoomIn"
leave-active-class="animate__animated animate__zoomOut" >
<div v-for="(msg,i) in msgs_data" v-bind:key="'msg' + msg.id" :id="'msg'+i" >
<div class="msgdate" v-if="msg.date">{{msg.date}}</div>
<div v-if="!msg.dest" class="right mmblock">
<div style="display: inline-block" class="message right" v-bind:key="'msgr' + i" >
<span class="msghour right">{{msg.hour}}</span>
<div class="row" style="text-align: left">
<div v-if="msg.mms" class="col-xs-12 col-sm-12 message-box" style="padding: 0">
<img v-if="photodata" :src="photodata" class="fullw mms">
<img v-else v-bind:src="'files/' + msg.mms" class="fullw mms" @click.stop="showMMS(msg.mms)">
</div>
<div v-if="msg.txt || msg.wave" class="col-xs-12 col-sm-12 message-box"
:style="{'background-color': color1, color: color2, filter: msg.selected ? 'invert(1)' : 'none'}"
@click.stop="selectMsg(msg)">
<span v-if="msg.cleared"><i>Ce message a été supprimé</i></span>
<span v-else>{{msg.txt}}</span>
<br>
<div v-if="msg.wave" style="width: 56vw;">
<div :id="'waveform' + i" style="display: inline-block; width: 48vw;"><img class="fullw" src="libs/wave.png"> </div>
<div class="d-inline-block pl-3" style="width:5vw;" @click="playwave(i)"> <i class="fas fa-play" style="position: relative; "></i></div>
</div>
</div>
</div>
<span v-if="msg.readmark">
<span v-if="msg.readmark == 'nonlu'">Non Lu</span>
<span v-else>Lu <i class="fa fa-check"></i></span>
</span>
</div>
</div>
<div v-if="msg.dest" class="left mmblock">
<span class="d-inline-block" style="vertical-align: bottom; margin-left: 1vw; margin-bottom: 1.2vw;">
<div class="destround" :style="{background: color3}">{{dest[0]}}</div>
</span>
<span class="msghour left">{{msg.hour}}</span>
<div style="display: inline-block; margin-left: 4%; margin-top: 0; vertical-align: top" class="message left" v-bind:key="'msgl' + i">
<div class="row vcenter">
<div v-if="msg.mms" class="col-xs-12 col-sm-12 message-box" style="padding: 0">
<img v-bind:src="'files/' + msg.mms" class="fullw mms" @click.stop="showMMS(msg.mms)">
</div>
<div v-if="msg.txt || msg.wave" class="col-xs-12 col-sm-12 message-box" :style="{filter: msg.selected ? 'invert(1)' : 'none'}" @click.stop="selectMsg(msg)">
<span v-if="msg.cleared"><i>Ce message a été supprimé</i></span>
<span v-else>{{msg.txt}}</span>
<br>
<div v-if="msg.wave" style="width: 56vw; margin-top: 15px">
<div :id="'waveform' + i" style="display: inline-block; width: 48vw;"><img class="fullw" src="libs/wave.png"> </div>
<div class="d-inline-block pl-3" style="width:5vw;" @click="playwave(i)"> <i class="fas fa-play" style="position: relative; "></i></div>
</div>
</div>
</div>
</div>
</div>
</div>
</transition-group>
<div class="message left" key="dots" v-if="dotsbox">
<div class="row vcenter">
<div class="col-xs-12 col-sm-12 message-box" style="line-height: 0.8; font-size: 2em">
<div class="center"><span class="dot">.</span><span class="dot">.</span><span class="dot">.</span></div>
</div>
</div>
</div>
<br><br><br>
</div>
</div>
<div class="win-footer">
<div class="inputblock" style="z-index: 10000" v-if="!counter">
<div class="d-inline-block text-center" @click="showKeyboard"
style="width: 13%; font-size: 1.2em; vertical-align: middle; padding-bottom: 1.8vw ">
<span class="fal fa-lg fa-microphone" v-if="send_msgs_data.length && send_msgs_data[0].wave" style="color: #3182c9"></span>
<span class="fal fa-lg fa-camera" v-else style="color: #3182c9"></span>
</div><div class="d-inline-block" style="width: 74%; vertical-align: bottom; padding-bottom: 5px; position: relative">
<div class="sendtxt">
<img v-if="photodata && send_msgs_data && send_msgs_data[0] && send_msgs_data[0].mms && !send_msgs_data[0].dest"
:src="photodata" class="fullw" style="padding-top: 30px; padding-left: 5%; padding-right: 5%;">
<img v-else-if="send_msgs_data && send_msgs_data[0] && send_msgs_data[0].mms && !send_msgs_data[0].dest" :src="'files/' + send_msgs_data[0].mms" class="fullw"
style="padding-top: 30px; padding-left: 5%; padding-right: 5%;">
<textarea rows="1" type="txt" class="form-control txtinput" id="txtinput" placeholder="Message" readonly> </textarea>
</div>
<i v-if="vocal" class="fa fa-microphone" style="position: absolute; top: 3.4vw; right: 5vw; color: #3182c9" @click.stop="showVocalKeyboard"></i>
</div><div class="text-center d-inline-block"
style="width: 13%; font-size: 1.2em; vertical-align: middle; padding-bottom: 1.8vw;">
<span class="fa-stack" style="font-size: 0.9em; padding-bottom: 20px" v-if="!loading" @click="sendMsg">
<i class="far fa-circle fa-stack-2x" style="color: #3182c9"></i>
<i class="fal fa-arrow-up fa-stack-1x" style="color: #3182c9"></i>
</span>
<div style="padding-bottom: 10px" v-if="loading">
<span class="fa fa-spinner fa-spin fa-fw"></span>
</div>
</div>
</div>
<br>
<div class="keyboard" v-if="keyboard" @click="writeTxt"><img src="libs/keyboard.png"></div>
<transition name="custom-classes-transition-zoom"
enter-active-class="animate__animated animate__fadeIn"
leave-active-class="animate__animated animate__fadeOut">
<div class="keyboard" v-if="vocalkeyboard" @click="writeTxt"
style="display: flex;flex-direction: column; align-items: center; justify-content: center; height: 25vh">
<div>
<span class="fa-stack fa-3x animate__animated animate__pulse animate__infinite" @click="writeTxt">
<i class="fa fa-circle fa-stack-2x" style="color:#68BFD0"></i>
<i class="fa fa-microphone fa-stack-1x" style="color: white"></i>
</span>
</div>
<h5 class="mt-3">Parlez...</h5>
</div>
</transition>
<transition name="custom-classes-transition-zoom"
enter-active-class="animate__animated animate__fadeIn"
leave-active-class="animate__animated vfast animate__fadeOut">
<div v-if="counter" @click.stop="stopRecord"
style="display: flex;flex-direction: column; align-items: center; justify-content: center; height: 25vh; background: rgb(94, 94, 94); background: linear-gradient(90deg, rgba(2,0,36,1) 0%, rgba(121,9,9,1) 100%);
border-radius: 10px; border: #CCC solid 2px; margin: 20px; color: white">
<div><h6>Enregistrement en cours...</h6></div>
<div>
<span class="fa-stack fa-3x animate__animated animate__pulse animate__infinite">
<i class="fa fa-circle fa-stack-2x" style="color: red"></i>
<i class="fa fa-microphone fa-stack-1x" style="color: white"></i>
</span>
</div>
<div @click.stop="counter_i = 0" class="mt-2">
<h5 class="mt-3"><i class="fas fa-circle" style="color: red"></i> {{counter}}</h5>
</div>
</div>
</transition>
</div>
</div>
<div>
<img class="fullw abstop ztop" src="libs/headbna.png">
<div class="user-dir">
<div class="win-head">
<div class="title" style="width: 100%">
<div style="display: inline-block; width: 72%; margin:0; padding: 3vw">
<span class="fal fa-arrow-left"></span> <span class="ml-3"> Composer</span>
</div><div style="display: inline-block; width: 28%; text-align: right">
<i class="fal fa-plus mr-3"></i>
</div>
</div>
<div class="nav" style="font-size: 0.8em; padding: 2vw; text-align: center; display: flex; align-items: center; justify-content: center;">
<div class="title active">Composer</div> <div class="title">Favoris</div> <div class="title">Répertoire</div>
<div class="title">Journal</div>
</div>
</div>
<div class="win-content" style="position: absolute; bottom: 0; left: 0; z-index: 10; background: #FFF; top: auto;">
<input type="text" id="numinput" class="numinput" readonly style="border: none">
<transition name="custom-classes-transition-zoom2"
enter-active-class="animate__animated animate__fadeIn"
leave-active-class="animate__animated animate__fadeOut" >
<div class="p-1 pl-3 pr-3 border" v-if="autocomplete_selected">
<div style="display: inline-block; width: 15%; vertical-align: top; text-align: left;">
<span class="fa-stack" ><i class="fas fa-circle fa-stack-2x" style="color: #999"></i><i class="fal fa-user fa-stack-1x" style="color: white"></i></span>
</div><div style="display: inline-block; width: 85%">
<div style="font-size: 1.2em;">
{{autocomplete_selected.name}}
<span class="fa-stack phone-but"><i class="fal fa-phone fa-stack-1x" style="color: green"></i></span>
</div>
<div style="font-size: 0.6em; color: grey;"><div > <i class="fal fa-phone mr-2"></i> <i><span>{{autocomplete_selected.number}}</span> </i></div></div>
</div>
</div>
</transition>
<img src="libs/numkey.png" id="numkey" class="numkey" @click="numerote">
<img src="libs/call.png" id="numcall" class="numcall fullw" @click="call">
<img src="libs/iconsbot.png" style="width: 100%; filter: invert(1)">
</div>
</div>
</div>
<div>
<img class="fullw abstop ztop" src="libs/headbna.png" style="background: #F0F0F0">
<div class="user-dir">
<div class="win-head">
<div class="title" style="width: 100%">
<div style="display: inline-block; width: 72%; margin:0; padding: 3vw">
<span class="fal fa-arrow-left"></span> <span class="ml-3"> Répertoire</span>
</div><div style="display: inline-block; width: 28%; text-align: right">
<i class="fal fa-plus mr-3"></i>
</div>
</div>
<div class="nav" style="font-size: 0.8em; padding: 2vw; text-align: center; display: flex; align-items: center; justify-content: center;">
<div class="title">Composer</div> <div class="title">Favoris</div> <div class="title" @click.stop="historypage = false" v-bind:class="{active : !historypage}">Répertoire</div>
<div class="title" v-bind:class="{active : historypage}" @click.stop="historypage = true">Journal</div></div>
</div>
<div class="win-content">
<div v-if="historypage">
<div class="dirtitle">Journal des Appels</div>
<transition-group name="list-complete" tag="ul" class="list-group">
<li class="list-group-item list-complete-item" v-for="(entry, i) in hentries" v-bind:key="'entry3' + i"
@click="selectHEntry(i);" v-bind:class="{selected : selected[i]}">
<div style="display: inline-block; width: 15%; vertical-align: top; text-align: left;">
<span class="fa-stack" v-if="!entry.avatar" style="font-size: 5.6vw">
<i class="far fa-circle-thin fa-stack-2x" style="color: #999"></i>
<i class="fal fa-user fa-stack-1x" style="color: #999"></i>
</span>
</div><div style="display: inline-block; width: 85%">
<div>
<img v-if="entry.avatar" v-bind:src="'files/' + entry.avatar" class="img rounded-circle avatarimg">
{{entry.name}}
<span class="fa-stack phone-but fa-lg"><i class="fal fa-phone fa-stack-1x" style="color: green"></i></span>
</div>
<div style="font-size: 0.6em; color: grey;"><div v-if="entry.hdetails"> <i class="fal fa-phone mr-2"></i> <i> <span v-html="entry.hdetails"></span> </i></div></div>
</div>
</li>
</transition-group>
</div>
<div v-if="!historypage">
<div class="dirtitle">Favoris <i class="fa fa-star-o"></i></div>
<transition-group name="list-complete" tag="ul" class="list-group" style="margin-bottom: 0">
<li class="list-group-item list-complete-item" v-for="(entry, i) in fentries" v-bind:key="'entry'+i"
@click="selectFEntry(i);" v-bind:class="{selected : fselected[i]}">
<span class="fa-stack" v-if="!entry.avatar" style="font-size: 5.6vw"><i class="fas fa-circle fa-stack-2x" style="color: #999"></i><i class="fal fa-user fa-stack-1x" style="color: white"></i></span>
<img v-if="entry.avatar" v-bind:src="'files/' + entry.avatar" class="img rounded-circle avatarimg">
{{entry.name}}
<span class="fa-stack phone-but"><i class="fal fa-phone fa-stack-1x" style="color: green"></i></span>
</li>
</transition-group>
<div class="dirtitle">Tous</div>
<transition-group name="list-complete" tag="ul" class="list-group">
<li class="list-group-item list-complete-item" v-for="(entry, i) in entries" v-bind:key="'entry2' + i"
@click="selectEntry(i);" v-bind:class="{selected : selected[i]}">
<span class="fa-stack" v-if="!entry.avatar" style="font-size: 5.6vw"><i class="fas fa-circle fa-stack-2x" style="color: #999"></i><i class="fal fa-user fa-stack-1x" style="color: white"></i></span>
<img v-if="entry.avatar" v-bind:src="'files/' + entry.avatar" class="img rounded-circle avatarimg">
{{entry.name}}
<span class="fa-stack phone-but"><i class="fal fa-phone fa-stack-1x" style="color: green"></i></span>
</li>
</transition-group>
</div>
</div>
</div>
<img src="libs/iconsbot.png" style="position: absolute; bottom: 0; left: 0; width: 100%; filter: invert(1)">
</div>
<div class="phone" @click="showNotif" :style="{'background-image': avatar_bg && (phonein || force_avatar_bg) ? 'url(\'files/' + avatar_bg + '\')' : 'linear-gradient(' + color1 + ' 0%, ' + color2 + ' 100%)'}">
<transition name="fade">
<div class="fullw fullh abstop" style="z-index: 1000000000000000; background: #00FF00" v-if="fullgreen" @click.stop="nextPhoneStatut">
</div>
</transition>
<img class="head" src="libs/headwna.png">
<transition name="fade">
<div class="text-center doublecall ztop" v-if="showdcall" key="dcall">
<div style="margin-bottom: 3vw"><span class="text-muted">DOUBLE APPEL</span> <i class="fal fa-phone ml-2" style="color: green"></i></div>
<div v-if="dcallimg">
<img :src="'files/' + dcallimg" class="fullw" style="padding: 20px; border-radius: 4px">
</div>
<div style="margin-bottom: 3vw; font-size: 1.2em"><b>{{dcall}}</b></div>
<div class="text-center">
<div style="background: green" class="animate__animated animate__pulse animate__infinite dcallbut" @click="answerdcall">Répondre</div>
<div style="background: red" class="dcallbut" @click="rejectdcall">Refuser</div>
</div>
</div>
</transition>
<div class="notifications" style="top: 10vh" v-if="notif && notif.active" >
<transition name="custom-classes-transition-bounce"
enter-active-class="animate__animated animate__bounceInLeft"
leave-active-class="animate__animated animate__bounceOutRight" >
<div class="panel panel-default notification" v-if="notif.visible" @click.stop="hideNotif" key="n1">
<div class="row" style="margin-bottom: 15px;">
<div class="vvcenter" style="width: 16%">
<img src="libs/icomsg.png" class="fullw img img-fluidx">
</div>
<div class="vvcenter" style="color: #9D9D9C; width: 50%; padding-left: 3%; font-size: 1.2em">
<span>MESSAGES</span>
</div>
<div class="vvcenter" style="color: #9D9D9C; width: 28%; text-align: right; font-size: 0.9em;">
<em class="notifdate">maintenant</em>
</div>
</div>
<div class="row">
<div class="vvcenter">
<div><span class="numtel"><strong>{{notif.author}}</strong></span></div>
<div>{{notif.txt}}</div>
</div>
</div>
</div>
</transition>
</div>
<transition name="fade">
<div @click="soundslider = false" v-if="sslider && soundslider" class="fullw abstop" style="z-index: 1000000000000000; height: 100vh">
<div class="soundslider" key="sslider">
<div class="row">
<div class="col-xs-2"><i class="fal fa-volume-down"></i></div>
<div class="col-xs-8" style="padding-top: 3vw"><input type="range" min="1" max="100" value="50" class="slider" id="myRange"></div>
<div class="col-xs-2"><i class="fal fa-volume-up"></i></div>
</div>
<div class="row"><h5>Volume</h5></div>
</div>
</div>
</transition>
<div v-if="!avatar || (avatar_bg && (phonein || force_avatar_bg))" class="emptydiv" :style="{height: emptyh || '30vw'}"></div>
<div class="item text-center">
<div class="statut" :class="{blink_me: !counter && !endcall, warning: !counter, counter: !!counter}">{{statut}}</div>
<div class="identity" style="font-size: 1.5em; text-align: center">
{{displayname}}
<div style="font-size: 0.4em">Mobile</div>
</div>
</div>
<div v-if="!avatar || (avatar_bg && (phonein || force_avatar_bg))" class="emptydiv2" :style="{height: emptyh2 || '0'}"></div>
<div class="avatar item text-center" v-if="avatar && (!avatar_bg || (!phonein && !force_avatar_bg))" :class="{big: phonein}">
<img v-bind:src="'files/' + avatar" class="img img-thumbnail rounded-circle img-fluid" style="padding: 0.10rem">
</div>
<transition name="fade">
<div class="utils-buttons item" v-if="!phonein" key="utils-button">
<div>
<div class="d-inline-block">
<div>
<span class="fa-stack fa-lg animate__infinite animate__pulse" @click.stop="hp = !hp">
<i class="fas fa-circle fa-stack-2x" v-bind:class="{selected : hp}" v-if="!force_avatar_bg"></i>
<i class="fal fa-volume-up fa-stack-1x" v-bind:class="{btnselect : hp}"></i>
</span>
</div>
<div class="buttonlegend">HP</div>
</div>
<div class="d-inline-block">
<div><span class="fa-stack fa-lg"><i class="fal fa-headphones fa-stack-1x"></i></span></div>
<div class="buttonlegend">Casque</div>
</div>
<div class="d-inline-block">
<div><span class="fa-stack fa-lg" @click.stop="nomic = !nomic"><i class="fal fa-microphone-slash fa-stack-1x" v-bind:class="{btnselect : nomic}"></i></span></div>
<div class="buttonlegend">Mic</div>
</div>
</div>
<div>
<div class="d-inline-block">
<div><span class="fa-stack fa-lg"><i class="fab fa-bluetooth-b fa-stack-1x" v-bind:class="{btnselect : bt}"></i></span></div>
<div class="buttonlegend">BT</div>
</div>
<div class="d-inline-block">
<div><span class="fa-stack fa-lg"><i class="fal fa-video fa-stack-1x"></i></span></div>
<div class="buttonlegend">Video</div>
</div>
<div class="d-inline-block">
<div><span class="fa-stack fa-lg"><i class="fal fa-users fa-stack-1x"></i></span></div>
<div class="buttonlegend">Groupe</div>
</div>
</div>
</div>
</transition>
<div class="call-buttons item" v-if="!phonein">
<span class="fa-stack fa-lg animate__pulse animate__infinite" v-bind:class="{animate__animated: statut == 'Connexion'}" @click.stop="nextPhoneStatut">
<i class="fas fa-circle fa-stack-2x" v-bind:class="{red: !endcall, grey: endcall}"></i>
<i class="fas fa-phone fa-stack-1x fa-inverse fa-flip-vertical"></i>
</span>
</div>
<div class="call-buttons item" v-if="phonein">
<div class="phone-buttons">
<span class="fa-stack fa-lg greyw"><span class="fal fa-volume-up fa-stack-1x"></span></span>
<span class="fa-stack fa-lg grey"><span class="fal fa-volume-down fa-stack-1x"></span></span>
<span class="fa-stack fa-lg animate__pulse animate__infinite" v-bind:class="{white: nosnd, grey: !nosnd, animate__animated: nosnd}" @click.stop="nosnd = !nosnd"><span class="fal fa-volume-off fa-stack-1x"></span></span>
</div>
<div class="phone-buttons" >
<span class="fa-stack fa-lg animate__infinite animate__pulse animate__animated" @click.stop="nextPhoneStatut">
<i class="fas fa-circle fa-stack-2x ripple" v-bind:class="{green: !endcall, grey: endcall}"></i>
<i v-if="!videoin" class="fas fa-phone fa-stack-1x fa-inverse"></i>
<i v-else class="fal fa-video fa-stack-1x fa-inverse"></i>
</span>
<span class="fa-stack fa-lg"><span class="fas fa-comment fa-stack-1x"></span></span>
<span class="fa-stack fa-lg" @click.stop="rejectCall">
<i class="fas fa-circle fa-stack-2x" v-bind:class="{red: !endcall, grey: endcall}"></i>
<i v-if="!videoin" class="fas fa-phone fa-stack-1x fa-inverse fa-flip-vertical"></i>
<i v-else class="fal fa-times fa-stack-1x fa-inverse"></i>
</span>
</div>
</div>
</div>