1102 lines
37 KiB
HTML
Executable File
1102 lines
37 KiB
HTML
Executable File
<div id="chat">
|
||
<div id="chat_chan">
|
||
<p class="tab_bar"><span id="join_chan" class="chan round_top clickable"></span></p>
|
||
</div>
|
||
<div id="sidebar">
|
||
<div class="sidebar_box round">
|
||
<div class="sidebar_box_title round_top round clickable">Connectés</div>
|
||
<div id="connected_users" class="sidebar_box_content hide"></div>
|
||
</div>
|
||
<div class="sidebar_box round">
|
||
<div class="sidebar_box_title round_top round clickable">News</div>
|
||
<div id="news" class="sidebar_box_content hide"><p class="loading"><i class="fa fa-spin fa-inline fa-c-loading"></i></p></div>
|
||
</div>
|
||
<div class="sidebar_box round">
|
||
<div class="sidebar_box_title round_top round clickable">Aide</div>
|
||
<div id="help_open" class="sidebar_box_content help_paperclip clickable hide"></div>
|
||
</div>
|
||
</div>
|
||
<div id="chat_room" class="round">
|
||
<div id="chat_container">
|
||
<div id="chat_messages_box">
|
||
<div id="chat_messages"></div>
|
||
</div>
|
||
</div>
|
||
<div id="chat_input" class="round">
|
||
<form id="chat_form" name="chat_form">
|
||
|
||
</form>
|
||
</div>
|
||
</div>
|
||
<div id="template" class="hide">
|
||
<div id="message_input">
|
||
<i id="message_img" class="fa fa-fw fa-20 fa-c-comment"></i>
|
||
<input type="text" id="message" name="message" value="" maxlength="500" autofocus />
|
||
<input type="hidden" id="chan" name="chan" value="" maxlength="50" />
|
||
<i id="upload_img" class="fa fa-fw fa-20 fa-c-image"></i>
|
||
</div>
|
||
<div id="help" class="help tiny_round">
|
||
<p class="title">Manuel d'utilisation</p>
|
||
<p class="title righty"> <span id="close_help" class="clickable"><i class="fa fa-30 fa-c-close"></i></span></p>
|
||
<p class="subtitle"><span>Message</span></p>
|
||
<p class="item"><span class="key">Echap</span>Supprime le texte en cours de rédaction</p>
|
||
<p class="item"><span class="key">Flèche haut</span>Répète dernier message envoyé</p>
|
||
<p class="item"><span class="key">@X Y</span>Vous dites Y à X (pseudo de Y en rouge)</p>
|
||
<p class="item"><span class="key">/me X</span>Votre_pseudo X. Utile lorsque vous voulez parler de vous à la 3ème personne. Par exemple : /me se touche la nouille au taff</p>
|
||
<p class="item"><span class="key">/mail X Y</span>Vous envoyez à X un email contenant Y (adresse professionnelle)</p>
|
||
<p class="item"><span class="key">/news X</span>Vous annoncez le message X (votre message est ajouté à la liste des news automatiquement)</p>
|
||
<p class="item">
|
||
<span class="key">Tab</span>
|
||
Chaque hit pré-remplie le message en faisant défiler la liste des connectés.
|
||
Il est possible d'écrire la/les premières lettres afin de faire commencer le défilement aux pseudos commençant par ces lettre-ci.
|
||
Le fonctionnement demeure le même si l'on fait précéder le pseudo par @
|
||
</p>
|
||
<p class="subtitle"><span>Chans</span></p>
|
||
<p class="item">Les chans sont divisés en trois catégories : les chans privés (PM, pour deux personnes seulement), les chans entreprise (pour toutes les personnes d'une même entreprise) et les autres (chans publiques)</p>
|
||
<p class="item"><span class="key">/join #X</span>Vous rejoignez le chan X (si autorisé)</p>
|
||
<p class="item"><span class="key">/invite X</span>Vous invitez X à rejoindre le chan (si autorisé)</p>
|
||
<p class="item"><span class="key">/pm #X</span>Vous rejoignez le chan privé (vous et X)</p>
|
||
<p class="item"><span class="key">/quit #X</span>Vous quittez le chan X</p>
|
||
<p class="item"><span class="key">/chans</span>Liste des chans publiques disponibles (aussi accessible via /channels et /list)</p>
|
||
<p class="subtitle"><span>Options</span></p>
|
||
<p class="item"><span class="key">/nick X</span>Vous changez votre peudo en X</p>
|
||
<p class="item"><span class="key">/mission X</span>Vous changez votre affectation de mission</p>
|
||
<p class="subtitle"><span>Broutilles</span></p>
|
||
<p class="item"><span class="key">/9gag X</span>Vous postez le lien 9gag X (URL) dans le chat (utilisable comme proxy)</p>
|
||
<p class="item"><span class="key">/img X</span>Vous postez l'image X (URL) dans le chat (utilisable comme proxy)</p>
|
||
<p class="item"><span class="key">/now</span>Horloge parlante</p>
|
||
<p class="item"><span class="key">/like</span>Vous plussoyez</p>
|
||
<p class="item"><span class="key">/slap X</span>Vous foutez une grosse tarte à X</p>
|
||
<p class="item"><span class="key">/bs X</span>Vous bitch-slappez X</p>
|
||
<p class="item"><span class="key">/kick X</span>Vous mettez un coup de pied au cul à X</p>
|
||
<p class="item"><span class="key">/mean</span>Vous dites une insulte au hasard</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<script type="text/javascript">
|
||
databap.pageInit = function()
|
||
{
|
||
//Page constant
|
||
databap.consts.chanPrefix = 'chan_';
|
||
databap.consts.chanQuitPrefix = 'quit_chan_';
|
||
databap.consts.chanUnreadPrefix = 'unread_chan_';
|
||
|
||
//Page variables
|
||
self.tmp('sending_msg', 'boolean');
|
||
self.tmp('refresh', 'boolean');
|
||
self.tmp('unread_msg', 'object');
|
||
self.tmp('news_period', 10*60*1000);
|
||
self.tmp('get_news', false);
|
||
self.tmp('last_message_id', '0');
|
||
self.tmp('scrolling', 'boolean');
|
||
databap.tmp('tab_info', 'object');
|
||
|
||
//Main elements
|
||
$MsgInput = databap.getMainElem('#message');
|
||
$MsgInputBox = databap.getMainElem('#chat_input');
|
||
|
||
//Bind message box key events
|
||
databap.getMainElem('#chat_form').submit(function(e){e.preventDefault();});
|
||
$MsgInput.bind('keydown', function(e){if(e.which == 9)e.preventDefault();});
|
||
$MsgInput.keyup(function(e){keyController(e);});
|
||
|
||
//Loading the chat
|
||
self.initScrollBar('#chat_container', '#chat_messages_box', '#chat_messages');
|
||
|
||
//Loading Chans
|
||
setChanButton();
|
||
databap.vars.chans_list[databap.consts.all_chan_id] = databap.consts.all_chan_text;
|
||
databap.tmp(['unread_msg', databap.consts.all_chan_text], 0);
|
||
joinChan(databap.consts.default_chan, true);
|
||
|
||
//window focus
|
||
$(window).focus(onPageFocus);
|
||
$(window).blur(onPageBlur);
|
||
|
||
//Message Input Focus
|
||
$MsgInput.focus();
|
||
|
||
//Init sidebar events
|
||
initSideBar();
|
||
|
||
//Setup Image upload
|
||
initImageUpload();
|
||
|
||
//Init's end
|
||
databap.setInitEnd(true);
|
||
|
||
//Notification Permission
|
||
if(!Push.Permission.has()) Push.Permission.request(()=>{}, ()=>{});
|
||
};
|
||
|
||
//On resize
|
||
databap.onResize = function()
|
||
{
|
||
self.setScrollBarSize('maximize');
|
||
|
||
//Message Input
|
||
//$('#message').width($('#chat_input').width() - $('#message_img').outerWidth(true)- 1);
|
||
};
|
||
|
||
//Disconnect from the chat
|
||
databap.onQuit = function()
|
||
{
|
||
if(databap.tmp('refresh') == false) databap.getSyncInfo('disconnect_chat');
|
||
databap.vars.chans_list = {};
|
||
if(typeof oChatTimer != "undefined") clearTimeout(oChatTimer);
|
||
if(typeof oUserTimer != "undefined") clearTimeout(oUserTimer);
|
||
return true;
|
||
};
|
||
|
||
databap.onKeyDown = function(e)
|
||
{
|
||
if(e.keyCode == 116) databap.tmp('refresh', true);
|
||
else databap.tmp('refresh', false);
|
||
};
|
||
|
||
function initImageUpload()
|
||
{
|
||
//Load Uploader
|
||
self.tmp('uploader', new qq.FileUploader
|
||
(
|
||
{
|
||
element: document.getElementById('chat_form'),
|
||
action: databap.getActionLink('upload_image'),
|
||
allowedExtensions: databap.consts.authorized_img_exts,
|
||
sizeLimit: parseInt(databap.consts.max_size)*100,
|
||
template: '<div class="uploader_box">' +
|
||
'<div class="uploader_droparea round">' +
|
||
'<span>Glisser les images ici</span>' +
|
||
'</div>' +
|
||
'<a class="uploader_button hide"></a>' +
|
||
'<div class="uploader_buffer hide"></div>' +
|
||
'<ul id="uploader_list" class="uploader_list hide"></ul>' +
|
||
'</div>',
|
||
onComplete:function(id, fileName, result)
|
||
{
|
||
if(result.success==true)
|
||
{
|
||
postMessage('/img '+result.file_path+result.file_name);
|
||
}
|
||
},
|
||
onProgress:function(id, fileName, loaded, total)
|
||
{
|
||
databap.feedback('success', 'Télécharge: '+(loaded/total*100)+'%', true);
|
||
},
|
||
showMessage:function(sMsg)
|
||
{
|
||
databap.feedback('error', sMsg);
|
||
},
|
||
debug: false,
|
||
stepId: 1
|
||
}
|
||
));
|
||
$('.uploader_box').append($('#message_input').children());
|
||
|
||
//Prompt file explorer
|
||
$('#upload_img').click(function(){$('#c1_file').click();});
|
||
|
||
//Clipboard handling
|
||
$(function(){$.pasteimage(function(sSource)
|
||
{
|
||
//Parse the uri to strip out "base64"
|
||
var sSourceSplit = sSource.split("base64,");
|
||
var sSourceString = sSourceSplit[1];
|
||
|
||
//Write base64-encoded string into input field
|
||
postMessage('/imgsrc '+sSourceString);
|
||
});});
|
||
}
|
||
|
||
function initSideBar()
|
||
{
|
||
//Sidebar Events
|
||
$('#sidebar').find('.sidebar_box_title').click
|
||
(
|
||
function()
|
||
{
|
||
$This = $(this);
|
||
if(!$This.closest('.sidebar_box').find('.sidebar_box_content').is(":visible"))
|
||
{
|
||
$('#sidebar').find('.sidebar_box_title').not($This)
|
||
.addClass('round')
|
||
.closest('.sidebar_box').find('.sidebar_box_content')
|
||
.hide('fast');
|
||
|
||
$This
|
||
.toggleClass('round')
|
||
.closest('.sidebar_box').find('.sidebar_box_content')
|
||
.toggle('fast', function()
|
||
{
|
||
databap.resizeMain('true');
|
||
switch($(this).attr('id'))
|
||
{
|
||
case 'help_open': $('#help_open').click(); break;
|
||
case 'news': getNews(); break;
|
||
}
|
||
});
|
||
}
|
||
}
|
||
);
|
||
$('#sidebar').find('.sidebar_box_title').eq(0).click();
|
||
|
||
//Help
|
||
databap.getMainElem('#help_open').click(displayHelp);
|
||
}
|
||
|
||
function getNews()
|
||
{
|
||
if(typeof databap.tmp('news_timer') != "undefined") clearTimeout(databap.tmp('news_timer'));
|
||
var $NewsBox = $('#news');
|
||
if($NewsBox.is(':visible'))
|
||
{
|
||
databap.getInfo
|
||
(
|
||
'news',
|
||
function(asNews)
|
||
{
|
||
if(Object.keys(asNews.news).length>0)
|
||
{
|
||
$.each(asNews.news, function(ikey, asNew)
|
||
{
|
||
$('<div>', {'class':'new'}).hide()
|
||
.append($('<p>')
|
||
.append($('<i>', {'class':'fa fa-inline fa-30 fa-c-news'}))
|
||
.append($('<span>').text(asNew.message)))
|
||
.append($('<p>', {'class':'signature'})
|
||
.text('—'+asNew.nickname)
|
||
.append('<br />')
|
||
.append($('<span>', {'class':'news_time'}).text(asNew.time_desc)))
|
||
.appendTo($NewsBox);
|
||
});
|
||
}
|
||
else $('<div>', {'class':'new'}).hide().text('Aucune news.').appendTo($NewsBox);
|
||
|
||
$NewsBox.find('.loading').hide();
|
||
$NewsBox.find('.new').toggle();
|
||
$NewsBox.find('.new:hidden').remove();
|
||
|
||
//Request in 10mins
|
||
databap.tmp('news_timer', setTimeout(getNews, databap.tmp('news_period')));
|
||
},
|
||
{},
|
||
'json'
|
||
);
|
||
}
|
||
}
|
||
|
||
function onPageFocus()
|
||
{
|
||
//debug('focusing');
|
||
databap.vars.focus = true;
|
||
switchChan();
|
||
}
|
||
function onPageBlur()
|
||
{
|
||
//debug('blurring');
|
||
databap.vars.focus = false;
|
||
}
|
||
|
||
function setChanButton()
|
||
{
|
||
$('#join_chan')
|
||
//.click(function(){$('#join_chan_button').click();})
|
||
.append
|
||
(
|
||
$('<span>', {id:'join_chan_button'})
|
||
.click(function()
|
||
{
|
||
$(this).hide();
|
||
$('#join_chan_input').css('display', '');
|
||
$('#join_chan').addClass('active').find('#input_chan').focus();
|
||
})
|
||
.append(' ')
|
||
.append($('<i>', {'class':'fa fa-c-plus'}))
|
||
.append(' ')
|
||
)
|
||
.append
|
||
(
|
||
$('<span>', {id:'join_chan_input'})
|
||
.append($('<span>', {'class':'hash'}).text('#'))
|
||
.append
|
||
(
|
||
$('<input>', {type:'text', id:'input_chan', 'class':'round'})
|
||
.keyup(function(e)
|
||
{
|
||
if(e.keyCode == 13)
|
||
{
|
||
var $This = $(this);
|
||
joinChan($This.val());
|
||
$This.val('');
|
||
|
||
}
|
||
if(typeof e.keyCode == 'undefined' || e.keyCode == 13)
|
||
{
|
||
$('#join_chan_input').css('display', 'none');
|
||
$('#join_chan_button').show();
|
||
$('#join_chan').removeClass('active');
|
||
}
|
||
})
|
||
.blur(function(){$(this).keyup();})
|
||
).hide()
|
||
);
|
||
}
|
||
|
||
function getChanKeyName(sChanName)
|
||
{
|
||
var sChanKeyName = false;
|
||
//$.each(databap.vars.chans_list, function(sConnChanKeyName, sConnChanName){if(sConnChanName==sChanName) sChanKeyName=sConnChanKeyName;});
|
||
for(var i in databap.vars.chans_list) {if(databap.vars.chans_list[i]==sChanName){sChanKeyName=i;break;}}
|
||
return sChanKeyName;
|
||
}
|
||
function getChanName(sChanKeyName)
|
||
{
|
||
return (typeof databap.vars.chans_list[sChanKeyName] == 'undefined')?false:databap.vars.chans_list[sChanKeyName];
|
||
}
|
||
|
||
function joinPmChan()
|
||
{
|
||
var iTargetId = $(this).attr('id');
|
||
if(iTargetId!=databap.vars.user_id)
|
||
{
|
||
var sPmChan = (databap.vars.user_id < iTargetId)?databap.vars.user_id+databap.consts.pm_separator+iTargetId:iTargetId+databap.consts.pm_separator+databap.vars.user_id;
|
||
joinChan(sPmChan, false, [iTargetId]);
|
||
}
|
||
}
|
||
|
||
function joinChan(sChanName, bFirstConn, asAttendees, bSwitchOnJoin)
|
||
{
|
||
bFirstConn = bFirstConn || false;
|
||
asAttendees = asAttendees || [];
|
||
bSwitchOnJoin = (typeof bSwitchOnJoin === 'undefined')?true:bSwitchOnJoin;
|
||
var sChanName = ucwords(sChanName);
|
||
|
||
if(sChanName!='')
|
||
{
|
||
//Join for the first time
|
||
if(!getChanKeyName(sChanName))
|
||
{
|
||
//Check accessibility & bring back messages
|
||
databap.getInfo
|
||
(
|
||
'join_chan',
|
||
function(data)
|
||
{
|
||
if(data.result == databap.consts.error) databap.feedback('error', data.desc);
|
||
else
|
||
{
|
||
//Add to channels list
|
||
var sConnectedChanKeyName = '';
|
||
$.each
|
||
(
|
||
data.channels,
|
||
function(iChanId, sReturnedChanName)
|
||
{
|
||
//Add tab if not already there
|
||
if(!getChanName(iChanId)) addChanTab(iChanId, sReturnedChanName, data.channel_tab_names[iChanId], !bSwitchOnJoin);
|
||
}
|
||
);
|
||
|
||
//Full reload of messages
|
||
refresh_chat(true);
|
||
|
||
//Switch to the right chan
|
||
switchChan(bSwitchOnJoin?data.current_chan_id:null);
|
||
}
|
||
},
|
||
{chan:sChanName, first_conn:(bFirstConn?1:0), attendees:asAttendees},
|
||
'json',
|
||
function()
|
||
{
|
||
databap.addFailIcon('Chan non autorisé');
|
||
},
|
||
true
|
||
);
|
||
}
|
||
else
|
||
{
|
||
//Switch to the right chan
|
||
switchChan(bSwitchOnJoin?getChanKeyName(sChanName):null);
|
||
}
|
||
}
|
||
|
||
//Focus input bar
|
||
$('#message').focus();
|
||
}
|
||
|
||
function invite(sNickName, iChanId)
|
||
{
|
||
var iUserId = databap.tmp(['id_users', sNickName]);
|
||
if(iUserId>0)
|
||
{
|
||
databap.getInfo
|
||
(
|
||
'invite_chan',
|
||
function(data)
|
||
{
|
||
databap.feedback(data.result==databap.consts.success?'success':'error', data.desc);
|
||
},
|
||
{chan:iChanId, user:databap.tmp(['id_users', sNickName])},
|
||
'json'
|
||
);
|
||
}
|
||
else databap.feedback('error', 'Désolé, je connais pas cette personne !');
|
||
}
|
||
|
||
function currentChan(sChanName)
|
||
{
|
||
return (!sChanName)?$('#chan').val():$('#chan').val(sChanName).val();
|
||
}
|
||
|
||
function switchChan(sChanKeyName)
|
||
{
|
||
var sChanName = currentChan(getChanName(sChanKeyName));
|
||
sChanKeyName = sChanKeyName || getChanKeyName(sChanName);
|
||
|
||
//Unread msg
|
||
if(databap.vars.focus)
|
||
{
|
||
databap.tmp(['unread_msg', sChanName], 0);
|
||
databap.tmp(['unread_msg', databap.consts.all_chan_text], 0);
|
||
}
|
||
syncUnreadMsg();
|
||
|
||
//Switch current channel button to active
|
||
$('#chat_chan').find('span[id^="'+databap.consts.chanPrefix+'"]').removeClass('active').addClass('clickable');
|
||
$('#'+databap.consts.chanPrefix+sChanKeyName).addClass('active').removeClass('clickable');
|
||
|
||
//Show current channel messages
|
||
databap.getMainElem('#chat_messages').find('p').hide();
|
||
databap.getMainElem('#chat_messages').find('p.class_'+sChanKeyName+', p.class_'+databap.consts.all_chan_id).show();
|
||
|
||
//Update scrollbar
|
||
databap.updateScrollBar(self.tmp('scrolling')?'relative':'bottom');
|
||
|
||
//Show Current channel members
|
||
databap.getMainElem('#connected_users').find('p').hide();
|
||
databap.getMainElem('#connected_users').find('p.class_'+sChanKeyName).show();
|
||
}
|
||
|
||
function syncUnreadMsg()
|
||
{
|
||
//Global unread messages
|
||
var iCountUnread = 0;
|
||
$.each
|
||
(
|
||
databap.tmp('unread_msg'),
|
||
function(sChanName, iUnreadMsg)
|
||
{
|
||
iCountUnread += iUnreadMsg;
|
||
}
|
||
);
|
||
databap.setTitle((iCountUnread>0)?iCountUnread+' msg':'');
|
||
|
||
//Chan unread messages
|
||
var sChanUnreadId = '';
|
||
var sUnreadText = '';
|
||
iCountUnread = 0;
|
||
$.each
|
||
(
|
||
databap.vars.chans_list,
|
||
function(sChanKeyName, sChanName)
|
||
{
|
||
sChanUnreadId = databap.consts.chanUnreadPrefix+sChanKeyName;
|
||
iCountUnread = databap.tmp(['unread_msg', sChanName]);
|
||
sUnreadText = (iCountUnread > 0 && sChanName != currentChan())?' ('+iCountUnread+')':'';
|
||
databap.getMainElem('#'+sChanUnreadId).text(sUnreadText);
|
||
}
|
||
);
|
||
}
|
||
|
||
function addChanTab(sChanKeyName, sChanName, sChanTabName, bLightUp)
|
||
{
|
||
//Add channel to list
|
||
sChanTabName = sChanTabName || sChanName;
|
||
databap.vars.chans_list[sChanKeyName] = sChanName;
|
||
databap.tmp(['unread_msg', sChanName], 0);
|
||
|
||
//Add channel tab
|
||
var sChanId = databap.consts.chanPrefix+sChanKeyName;
|
||
if(!$('#'+sChanId).length)
|
||
{
|
||
//Prepare clickable chan button
|
||
var sChanQuitId = databap.consts.chanQuitPrefix+sChanKeyName;
|
||
var sChanUnreadId = databap.consts.chanUnreadPrefix+sChanKeyName;
|
||
var $ChanButton = $('<span id="'+sChanId+'" class="chan clickable inc_border round_top'+(bLightUp?' light_up':'')+'">#</span>')
|
||
.click(function(){$(this).removeClass('light_up');joinChan(databap.vars.chans_list[$(this).attr('id').substr(databap.consts.chanPrefix.length)]);})
|
||
.append('<span class="chan_title">'+sChanTabName+'</span>')
|
||
.append('<span class="chan_unread" id="'+sChanUnreadId+'"></span>')
|
||
.append($('<a id="'+sChanQuitId+'" class="quit_chan clickable"><i class="fa fa-c-close"></i></a>').click(function(e){e.stopPropagation();quitChan($(this).attr('id').substr(databap.consts.chanQuitPrefix.length));}));
|
||
|
||
|
||
//Add channel tab name and bind delete button
|
||
$('#join_chan').before($ChanButton);
|
||
}
|
||
}
|
||
|
||
function quitChan(sChanKeyName)
|
||
{
|
||
var sChanName = databap.vars.chans_list[sChanKeyName];
|
||
if(typeof sChanName != 'undefined' && Object.keys(databap.vars.chans_list).length > 1)
|
||
{
|
||
//delete on server
|
||
databap.getInfo
|
||
(
|
||
'quit_chan',
|
||
function(result){},
|
||
{chan:sChanName},
|
||
'text',
|
||
function(textStatus)
|
||
{
|
||
debug('Error chat.html quit channel');
|
||
databap.showError(textStatus);
|
||
}
|
||
);
|
||
|
||
//Delete tab
|
||
$('#'+databap.consts.chanPrefix+sChanKeyName).fadeOut('fast', function(){$(this).remove();});
|
||
|
||
//Delete from list
|
||
delete databap.vars.chans_list[sChanKeyName];
|
||
|
||
//Switch back to another chan
|
||
if(sChanName == currentChan()) switchChan(Object.keys(databap.vars.chans_list)[1]);
|
||
|
||
//Delete messages
|
||
databap.getMainElem('#chat_messages').find('p.class_'+sChanKeyName).remove();
|
||
}
|
||
else databap.addFailIcon('Ceci est le dernier chan');
|
||
}
|
||
|
||
function postMessage(sMsg)
|
||
{
|
||
sMsg = sMsg || '';
|
||
var bSuccess = true;
|
||
if(databap.tmp('sending_msg') == true)
|
||
{
|
||
databap.feedback('warning', 'Pas si pressé ! J\'ai pas encore envoyé le dernier message');
|
||
bSuccess = false;
|
||
}
|
||
else
|
||
{
|
||
if(sMsg!='')
|
||
{
|
||
databap.tmp('msg_buffer', $('#message').val());
|
||
$('#message').val(sMsg);
|
||
}
|
||
databap.tmp('sending_msg', true);
|
||
databap.saveForm
|
||
(
|
||
'add_message',
|
||
databap.getMainElem('#chat_form'),
|
||
function(oData)
|
||
{
|
||
databap.tmp('sending_msg', false);
|
||
if(oData.result==databap.consts.error) databap.feedback('error', oData.desc);
|
||
else refresh_chat();
|
||
},
|
||
true,
|
||
'json'
|
||
);
|
||
if(sMsg!='') $('#message').val(databap.tmp('msg_buffer'));
|
||
}
|
||
return bSuccess;
|
||
}
|
||
|
||
function keyController(e)
|
||
{
|
||
if(e.keyCode != 9) databap.tmp('tab_info', {}); //See case 9, tab
|
||
switch(e.keyCode)
|
||
{
|
||
case 13 : //enter
|
||
$this = databap.getMainElem('#message');
|
||
var chat_message = $this.val();
|
||
var bSuccess = true;
|
||
if(chat_message.substr(0, 7) == '/join #') joinChan(chat_message.substr(7));
|
||
else if(chat_message.substr(0, 7) == '/quit #') quitChan(getChanKeyName(chat_message.substr(7)));
|
||
else if(chat_message == '/help') displayHelp();
|
||
else if(chat_message.substr(0, 8) == '/invite ') invite($.trim(chat_message.substr(8)), currentChan());
|
||
else if(chat_message != '') bSuccess = postMessage();
|
||
|
||
if(bSuccess)
|
||
{
|
||
databap.vars.prev_chat_value = chat_message;
|
||
$this.val('');
|
||
}
|
||
break;
|
||
case 27 : //echap
|
||
databap.getMainElem('#message').val('');
|
||
break;
|
||
case 38 : //arrow up
|
||
$this = databap.getMainElem('#message');
|
||
var chat_message = $this.val();
|
||
if(chat_message=='' && typeof databap.vars.prev_chat_value !== 'undefined' && databap.vars.prev_chat_value!='')
|
||
{
|
||
$this.val(databap.vars.prev_chat_value);
|
||
}
|
||
break;
|
||
case 40 : //arrow down
|
||
$this = databap.getMainElem('#message');
|
||
var chat_message = $this.val();
|
||
if(typeof databap.vars.prev_chat_value !== 'undefined' && databap.vars.prev_chat_value==chat_message)
|
||
{
|
||
$this.val('');
|
||
}
|
||
break;
|
||
case 9 : //tab
|
||
$This = databap.getMainElem('#message');
|
||
var sChatMsg = $This.val();
|
||
var iChatMsgLen = sChatMsg.length;
|
||
|
||
if(!e.altKey && iChatMsgLen>0)
|
||
{
|
||
var iCurPos, iFirstPos, iOffset, sWord, sWordLen, bInvite;
|
||
|
||
//Loading previous data
|
||
bLooping = !$.isEmptyObject(databap.tmp('tab_info'));
|
||
if(bLooping)
|
||
{
|
||
sChatMsg = databap.tmp(['tab_info', 'chat_msg']);
|
||
iCurPos = databap.tmp(['tab_info', 'cur_pos']);
|
||
iFirstPos = databap.tmp(['tab_info', 'first_pos']);
|
||
sWord = databap.tmp(['tab_info', 'word']);
|
||
}
|
||
else
|
||
{
|
||
//Find word in chat message input box
|
||
iCurPos = $This.getCursorPosition();
|
||
iFirstPos = sChatMsg.substr(0, iCurPos).lastIndexOf(' ') + 1;
|
||
iOffset = sChatMsg.substr(iFirstPos).indexOf(' ');
|
||
sWord = sChatMsg.substr(iFirstPos, (iOffset==-1)?iChatMsgLen:iOffset);
|
||
|
||
//@ excluded
|
||
if(sWord.substr(0, 1)=='@')
|
||
{
|
||
iFirstPos++;
|
||
sWord = sWord.substr(1);
|
||
}
|
||
}
|
||
sWordLen = sWord.length;
|
||
bInvite = (sChatMsg.substr(0, 7) == '/invite');
|
||
|
||
//No guess if not at least one letter
|
||
if(sWordLen>0 || bInvite)
|
||
{
|
||
//turn to safename for matching
|
||
var sSafeWord = getSafeNickname(sWord);
|
||
var iSafeWordLen = sSafeWord.length;
|
||
|
||
//List of current channel users
|
||
var asUserList = databap.tmp(['users', bInvite?databap.consts.all_chan_id:getChanKeyName(currentChan())]);
|
||
var asSafeUserList = Object.keys(asUserList);
|
||
var iUserListLen = asSafeUserList.length;
|
||
|
||
//Starting list where we left off
|
||
var iCount = 0;
|
||
var iIndex = 0;
|
||
if(bLooping) iIndex = (Number(array_search(databap.tmp(['tab_info', 'safe_nickname']), asSafeUserList)) + 1)%iUserListLen;
|
||
|
||
//Looping on user names to find the one(s) starting with the searched word
|
||
while(iCount < iUserListLen)
|
||
{
|
||
//Checking for first letters of user names
|
||
if(sSafeWord == asSafeUserList[iIndex].substr(0, sSafeWord.length)) break;
|
||
|
||
//Looping to the top of the list once finished
|
||
iIndex = (iIndex + 1)%iUserListLen;
|
||
iCount++;
|
||
}
|
||
|
||
if(iCount !== iUserListLen)
|
||
{
|
||
//Replace text in message input box
|
||
var sBeforeWord = sChatMsg.substr(0, iFirstPos);
|
||
var sAfterWord = sChatMsg.substr(iFirstPos+sWordLen);
|
||
var sSafeNickName = asSafeUserList[iIndex];
|
||
var sNickName = asUserList[sSafeNickName];
|
||
$This.val(sBeforeWord+sNickName+sAfterWord);
|
||
$This.setCursorPosition((sBeforeWord+sNickName).length);
|
||
|
||
//Save value for tab-loops
|
||
if(bLooping) databap.tmp(['tab_info', 'safe_nickname'], sSafeNickName); //not saving index in case of user list refresh
|
||
else databap.tmp(['tab_info'], {'chat_msg':sChatMsg, 'cur_pos':iCurPos, 'first_pos':iFirstPos, 'word':sWord, 'safe_nickname':sSafeNickName});
|
||
}
|
||
else databap.feedback('warning', 'Aucun nickname commençant "'+sWord+'" par n\'a été trouvé');
|
||
}
|
||
}
|
||
break;
|
||
/*default:debug(e.keyCode);break;*/
|
||
/*
|
||
default:
|
||
$this = databap.getMainElem('#message');
|
||
$copy = databap.getMainElem('#copy_message');
|
||
$copy.text($this.val());
|
||
var maxSize = databap.getMainElem('#chat_input').width() - 16;
|
||
var iInputSize = $copy.width();
|
||
if(iInputSize < 100)
|
||
{
|
||
$this.width(100);
|
||
}
|
||
else if(iInputSize > maxSize)
|
||
{
|
||
$this.width(maxSize);
|
||
}
|
||
else
|
||
{
|
||
$this.width(iInputSize);
|
||
}
|
||
*/
|
||
}
|
||
}
|
||
|
||
function refresh_chat(bReset)
|
||
{
|
||
var bReset = (typeof bReset != 'undefined' && bReset == true);
|
||
self.tmp('scrolling', (!bReset && !databap.isScrollBarAtBottom()));
|
||
if(typeof oChatTimer != "undefined") clearTimeout(oChatTimer);
|
||
if(databap.vars.current_page == 'chat')
|
||
{
|
||
if(!databap.vars.loading)
|
||
{
|
||
if(bReset)
|
||
{
|
||
self.tmp('last_message_id', 0);
|
||
databap.getMainElem('#chat_messages').empty();
|
||
}
|
||
databap.getInfo
|
||
(
|
||
'messages',
|
||
function(result)
|
||
{
|
||
var prevLastMsgId = self.tmp('last_message_id');
|
||
updateUsersList = false;
|
||
if(prevLastMsgId < result.last_message_id || bReset)
|
||
{
|
||
//Update last read message id
|
||
self.tmp('last_message_id', Math.max(result.last_message_id, prevLastMsgId));
|
||
|
||
//Display messages
|
||
$.each
|
||
(
|
||
result.messages,
|
||
function(id_message, message_info)
|
||
{
|
||
addMessage(message_info, bReset);
|
||
}
|
||
);
|
||
|
||
//Image display
|
||
setImageDisplay();
|
||
|
||
//News
|
||
if(databap.tmp('get_news') === true && !bReset) getNews();
|
||
databap.tmp('get_news', false);
|
||
|
||
//Nicknames changes
|
||
if(updateUsersList === true || bReset)
|
||
{
|
||
refresh_users(); //which execute switchChan()
|
||
updateUsersList = false;
|
||
}
|
||
else switchChan();
|
||
}
|
||
},
|
||
{message_id:self.tmp('last_message_id')},
|
||
'json',
|
||
function(textStatus)
|
||
{
|
||
debug('Error chat.html 155');
|
||
databap.showError(textStatus);
|
||
}
|
||
);
|
||
oChatTimer = setTimeout(refresh_chat, databap.vars.focus?2000:5000);
|
||
}
|
||
else
|
||
{
|
||
oChatTimer = setTimeout(function(){refresh_chat(bReset);}, 500);
|
||
}
|
||
}
|
||
}
|
||
|
||
function addMessage(message_info, bReset)
|
||
{
|
||
message_info.nickname = message_info.nickname || '';
|
||
|
||
var sChanKeyName = message_info.id_chan;
|
||
var sMsgPrefix = '<a class="user clickable" title="Ecrire un PM à '+message_info.nickname+'">'+message_info.nickname+'</a><span class="console">></span>';
|
||
var msg_body = '';
|
||
var sUnreadChanName, iUnreadCount;
|
||
var bSystemMsg = false;
|
||
var bImage = false;
|
||
var sNotif = '';
|
||
|
||
switch(message_info.msg_class)
|
||
{
|
||
case databap.consts.msg_types.user:
|
||
msg_body = sMsgPrefix+'<span class="text">'+message_info.message+'</span>';
|
||
sNotif = message_info.nickname+' : '+message_info.message;
|
||
break;
|
||
case databap.consts.msg_types.news:
|
||
databap.tmp('get_news', true);
|
||
msg_body = '<span class="text action">'+message_info.nickname+' a une news : <span class="news"><i class="fa fa-30 fa-c-news"></i> '+message_info.message+' <i class="fa fa-30 fa-c-news"></i></span></span>';
|
||
sNotif = message_info.nickname+' a une news : '+message_info.message;
|
||
break;
|
||
case databap.consts.msg_types.add.code:
|
||
var url = databap.getInternalLink('code', message_info.message);
|
||
msg_body = '<span class="text">'+message_info.nickname+' a ajouté un nouveau code : <a href="'+url+'" target="_blank"><i class="fa fa-c-code fa-inline"></i>'+message_info.description+'</a></span>';
|
||
break;
|
||
case databap.consts.msg_types.edit.code:
|
||
var url = databap.getInternalLink('code', message_info.message);
|
||
msg_body = '<span class="text">'+message_info.nickname+' a modifié le code <a href="'+url+'" target="_blank"><i class="fa fa-c-code fa-inline"></i>'+message_info.description+'</a></span>';
|
||
break;
|
||
case databap.consts.msg_types.add.proc:
|
||
var url = databap.getInternalLink('proc', message_info.message);
|
||
msg_body = '<span class="text">'+message_info.nickname+' a ajouté une nouvelle procédure : <a href="'+url+'" target="_blank"><i class="fa fa-c-proc fa-inline"></i>'+message_info.description+'</a></span>';
|
||
break;
|
||
case databap.consts.msg_types.edit.proc:
|
||
var url = databap.getInternalLink('proc', message_info.message);
|
||
msg_body = '<span class="text">'+message_info.nickname+' a modifié la procédure <a href="'+url+'" target="_blank"><i class="fa fa-c-proc fa-inline"></i>'+message_info.description+'</a></span>';
|
||
break;
|
||
case databap.consts.msg_types.action:
|
||
msg_body = '<span class="text action">'+message_info.nickname+' '+message_info.message+'</span>';
|
||
break;
|
||
case databap.consts.msg_types['private']:
|
||
slicePos = message_info.message.indexOf(' ');
|
||
msgTargetUser = message_info.message.substr(1, slicePos - 1);
|
||
var msg = message_info.message.slice(slicePos + 1);
|
||
msg_body = '<a class="user clickable" title="Ecrire un PM à '+message_info.nickname+'">'+message_info.nickname+'</a><span class="console"> <span class="highlight">@'+msgTargetUser+'</span>></span><span class="text">'+msg+'</span>';
|
||
sNotif = message_info.nickname+' @'+msgTargetUser+' : '+msg;
|
||
break;
|
||
case databap.consts.msg_types.nick:
|
||
msg_body = '<span class="text">'+message_info.message+' (<a href="'+databap.getInternalLink('profil', message_info.id_user)+'" target="_blank"><i class="fa fa-c-profile fa-inline"></i>'+message_info.name+'</a>)</span>';
|
||
updateUsersList = true;
|
||
break;
|
||
case databap.consts.msg_types.conn:
|
||
updateUsersList = true;
|
||
msg_body = (!self.vars2('opt_console'))?'':'<span class="text action">'+message_info.nickname+' '+message_info.message+'</span>';
|
||
bSystemMsg = true;
|
||
break;
|
||
case databap.consts.msg_types.img:
|
||
message_info.message = {url:message_info.message[3], title:'Source : '+message_info.message[3], url_img:message_info.message[0], width:message_info.message[1], height:message_info.message[2]};
|
||
case databap.consts.msg_types['9gag']:
|
||
var msg = '<a href="'+message_info.message.url+'" target="_blank" title="'+message_info.message.title+'"><img src="'+message_info.message.url_img+'" width="'+message_info.message.width+'" height="'+message_info.message.height+'" class="proxy" /></a>';
|
||
msg_body = sMsgPrefix+'<span class="text">'+msg+'</span>';
|
||
bImage = true;
|
||
sNotif = message_info.nickname+' a posté une image';
|
||
break;
|
||
case databap.consts.msg_types.reboot:
|
||
if(!bReset)
|
||
{
|
||
msg_body = '<span class="text action">'+message_info.message+'</span>';
|
||
setTimeout(databap.refresh, databap.consts.reboot_delay*1000);
|
||
bSystemMsg = true;
|
||
}
|
||
break;
|
||
case databap.consts.msg_types.invite:
|
||
if(!bReset) joinChan(sChanKeyName, false, [], false);
|
||
bSystemMsg = true;
|
||
break;
|
||
case databap.consts.msg_types.article:
|
||
var url = databap.getInternalLink('a', message_info.message);
|
||
msg_body = '<span class="text action">'+message_info.nickname+' a trouvé un nouvel article sur un blog BI ('+message_info.domain+') : <a href="'+url+'" target="_blank"><i class="fa fa-c-article fa-inline"></i>'+message_info.art_title+'</a> ';
|
||
msg_body+= 'par <a title="Lien vers la page de l\'auteur" href="'+message_info.link_auth+'" target="_blank">'+message_info.name+'</a> ('+message_info.art_date+')'+'</span>';
|
||
break;
|
||
case databap.consts.msg_types.status:
|
||
updateUsersList = true;
|
||
databap.tmp('get_news', true);
|
||
msg_body = '<span class="text action">'+message_info.nickname+' '+message_info.message+'</span>';
|
||
break;
|
||
case databap.consts.msg_types.add.doc:
|
||
var url = databap.getInternalLink('doc', message_info.message);
|
||
msg_body = '<span class="text">'+message_info.nickname+' a ajouté une nouvelle documentation : <a href="'+url+'" target="_blank"><i class="fa fa-c-doc fa-inline"></i>'+message_info.description+'</a></span>';
|
||
break;
|
||
case databap.consts.msg_types.edit.doc:
|
||
var url = databap.getInternalLink('doc', message_info.message);
|
||
msg_body = '<span class="text">'+message_info.nickname+' a modifié la documentation <a href="'+url+'" target="_blank"><i class="fa fa-c-doc fa-inline"></i>'+message_info.description+'</a></span>';
|
||
break;
|
||
case databap.consts.msg_types.add.table:
|
||
var url = databap.getInternalLink('table', message_info.message);
|
||
msg_body = '<span class="text">'+message_info.nickname+' a ajouté une nouvelle table : <a href="'+url+'" target="_blank"><i class="fa fa-c-table fa-inline"></i>'+message_info.description+'</a></span>';
|
||
break;
|
||
case databap.consts.msg_types.edit.table:
|
||
var url = databap.getInternalLink('table', message_info.message);
|
||
msg_body = '<span class="text">'+message_info.nickname+' a modifié la table <a href="'+url+'" target="_blank"><i class="fa fa-c-table fa-inline"></i>'+message_info.description+'</a></span>';
|
||
break;
|
||
}
|
||
|
||
if(msg_body != '')
|
||
{
|
||
//Hide image button
|
||
$Msg = $(msg_body);
|
||
if(bImage)
|
||
{
|
||
var $Banner = $('<span>', {'class':'banner'})
|
||
.append($('<span>', {'class':'banner_title'}).text(message_info.message.title))
|
||
.addButton('close', 'Cacher les images', toggleImages, '', 'no_text no_bg');
|
||
$Banner.css({'top':'calc('+Math.round(message_info.message.height / -2)+'px + 4px)'});
|
||
$Banner.find('.banner_title').width(message_info.message.width - 31);
|
||
$Msg.find('a').addClass('img_box').append($Banner);
|
||
}
|
||
|
||
//Adding message to channel panel
|
||
$Message = $('<p>', {'class':message_info.msg_class+' class_'+sChanKeyName+' hide round_right'})
|
||
.append($('<span>', {'class':'time'}).text(((message_info.date==databap.consts.cur_date)?'':message_info.date+' - ')+message_info.time))
|
||
.append($Msg);
|
||
$Message.find('.chan_link').click(function(){joinChan($(this).find('.chan_text').text());});
|
||
$Message.find('.user').click(setPm);
|
||
databap.getMainElem('#chat_messages').append($Message);
|
||
|
||
//Unread messages
|
||
if(!bReset && !bSystemMsg /* && message_info.id_user!=databap.vars.user_id */)
|
||
{
|
||
sUnreadChanName = getChanName(message_info.id_chan);
|
||
iUnreadCount = (databap.tmp(['unread_msg', sUnreadChanName]) || 0) + 1;
|
||
databap.tmp(['unread_msg', sUnreadChanName], iUnreadCount);
|
||
|
||
//Desktop Notification
|
||
if(!databap.vars.focus && sNotif != '' && Push.Permission.has()) {
|
||
Push.create('Databap - '+message_info.nickname, {
|
||
body: sNotif,
|
||
icon: databap.consts.app_image_folder+(databap.tmp(['logos', message_info.id_user]) || 'logo_25.png'),
|
||
timeout: 4000,
|
||
onClick: function () {
|
||
window.focus();
|
||
this.close();
|
||
}
|
||
});
|
||
}
|
||
}
|
||
|
||
//Move to bottom if user is typing
|
||
if(message_info.id_user===databap.vars.user_id) self.tmp('scrolling', false);
|
||
}
|
||
}
|
||
|
||
function toggleImages()
|
||
{
|
||
databap.vars2('opt_chat_images', !databap.vars2('opt_chat_images'));
|
||
setImageDisplay();
|
||
}
|
||
function setImageDisplay()
|
||
{
|
||
var $Images = $('#chat_messages').find('.img_box');
|
||
$Images.toggleClass('hidden', !self.vars2('opt_chat_images'));
|
||
$Images.find('.banner .fa').toggleClass('fa-c-image', !self.vars2('opt_chat_images'));
|
||
$Images.find('.banner .fa').toggleClass('fa-c-close', self.vars2('opt_chat_images'));
|
||
$Images.find('.banner .button').attr('title', (self.vars2('opt_chat_images')?'Cacher':'Afficher')+' les images');
|
||
|
||
databap.updateScrollBar('bottom');
|
||
}
|
||
|
||
function refresh_users()
|
||
{
|
||
if(typeof oUserTimer != "undefined") clearTimeout(oUserTimer);
|
||
if(databap.vars.current_page == 'chat')
|
||
{
|
||
var delay = databap.consts.keep_alive / 10; //seconds
|
||
databap.getInfo
|
||
(
|
||
'connected_users',
|
||
function(result)
|
||
{
|
||
//empty current users list
|
||
databap.getMainElem('#connected_users').empty();
|
||
databap.tmp('users', {});
|
||
databap.tmp('id_users', {});
|
||
|
||
$.each
|
||
(
|
||
result,
|
||
function(sChankeyName, chan_info)
|
||
{
|
||
chan_info.sort(function(asUser1, asUser2){return asUser1.nickname>asUser2.nickname?1:-1;});
|
||
$.each
|
||
(
|
||
chan_info,
|
||
function(key, user_info)
|
||
{
|
||
//Add nickname to connected user list
|
||
var sNickName = user_info.nickname;
|
||
var sSafeNickName = getSafeNickname(sNickName);
|
||
databap.tmp(['users', sChankeyName, sSafeNickName], sNickName);
|
||
databap.tmp(['users', databap.consts.all_chan_id, sSafeNickName], sNickName);
|
||
databap.tmp(['id_users', sNickName], user_info.id_user);
|
||
databap.tmp(['logos', user_info.id_user], user_info.logo);
|
||
|
||
//Append name to user list box
|
||
var sProfileLink = databap.getInternalLink('profil', user_info.id_user);
|
||
var sMission = user_info.status || '';
|
||
var sLogoTitle = user_info.company+((sMission=='')?'':' (Mission : '+sMission+')');
|
||
var sPm = user_info.name+((user_info.id_user==databap.vars.user_id)?'':' (cliquez pour lancer une conversation privée)');
|
||
var $User = $('<p>', {'class':'connected_user class_'+sChankeyName})
|
||
.append($('<a>', {'class':'connected_user_logo', href:sProfileLink, title:sLogoTitle, target:'_blank'})
|
||
.append($('<img>', {src:databap.consts.app_image_folder+user_info.logo}))
|
||
.append((user_info.afk=='1')?$('<i>', {'class':'fa fa-c-afk afk'}):''))
|
||
.append($('<a>', {'class':'connected_user_name clickable '+sNickName.replace('"', '\''), id:user_info.id_user, title:sPm}).text(sNickName));
|
||
$User.find('.connected_user_name').click(joinPmChan);
|
||
databap.getMainElem('#connected_users').append($User);
|
||
}
|
||
);
|
||
}
|
||
);
|
||
switchChan();
|
||
},
|
||
{},
|
||
'json',
|
||
function(textStatus)
|
||
{
|
||
delay = 10;
|
||
}
|
||
);
|
||
|
||
//re-scheddule
|
||
oUserTimer = setTimeout(refresh_users, delay*1000);
|
||
}
|
||
}
|
||
|
||
function getSafeNickname(sNickName)
|
||
{
|
||
return sNickName.stripVowelAccent().toLowerCase();
|
||
}
|
||
|
||
function setPm()
|
||
{
|
||
var name = $(this).text();
|
||
|
||
//PM
|
||
var msg='';
|
||
var prevMsg = databap.getMainElem('#message').val();
|
||
if(prevMsg.substr(0, 1) == '@')
|
||
{
|
||
msg = prevMsg.substr(prevMsg.indexOf(' ')+1);
|
||
}
|
||
else
|
||
{
|
||
msg = prevMsg;
|
||
}
|
||
databap.getMainElem('#message').val('@'+name+' '+msg).focus();
|
||
}
|
||
|
||
function displayHelp()
|
||
{
|
||
//Get template
|
||
$Help = $('#help').clone().attr('id', 'help_'+Math.floor((Math.random()*1000)));
|
||
|
||
//Visible on all channels
|
||
$Help.find('p').addClass('class_'+databap.consts.all_chan_id);
|
||
$Help.appendTo('#chat_messages').slideDown('fast', function()
|
||
{
|
||
databap.updateScrollBar('bottom');
|
||
});
|
||
|
||
//Close button activation
|
||
$Help.find('#close_help').click(function()
|
||
{
|
||
$(this).closest('.help').slideUp('fast', function()
|
||
{
|
||
databap.updateScrollBar('bottom');
|
||
});
|
||
});
|
||
}
|
||
</script>
|