"use strict";
// Constants
window.MESSAGE_CHECK_INTERVAL={$ROUND%,{$MAX,3000,{$CONFIG_OPTION,chat_message_check_interval}}};
window.TRANSITORY_ALERT_TIME={$ROUND%,{$CONFIG_OPTION,chat_transitory_alert_time}};
window.LOGS_DOWNLOAD_INTERVAL=3000;
// Tracking variables
var last_message_id=-1;
var last_timestamp=0;
var last_event_id=-1;
var message_checking=false;
var no_im_html='';
var text_colour;
var opened_popups={};
var load_from_room_id=null;
var already_received_room_invites={};
var already_received_contact_alert={};
var instant_go=false;
var is_shutdown=false;
var all_conversations={};
// Code...
window.has_focus=true;
add_event_listener_abstract(window,'blur',function() { window.has_focus=false; });
add_event_listener_abstract(window,'focus',function() { window.has_focus=true; });
function play_sound_url(url) // Used for testing different sounds
{
if (typeof window.soundManager=='undefined') return;
var base_url=((url.indexOf('data_custom')==-1)&&(url.indexOf('uploads/')==-1))?'{$BASE_URL_NOHTTP;}':'{$CUSTOM_BASE_URL_NOHTTP;}';
var sound_object=window.soundManager.createSound({url: base_url+'/'+url});
if (sound_object) sound_object.play();
}
function play_chat_sound(s_id,for_member)
{
if (typeof window.soundManager=='undefined') return;
var play_sound=window.document.getElementById('play_sound');
if ((play_sound) && (!play_sound.checked)) return;
if (for_member)
{
var override=window.top_window.soundManager.getSoundById(s_id+'_'+for_member,true);
if (override)
{
s_id=s_id+'_'+for_member;
}
}
if (typeof window.top_window.console!='undefined')
{
window.top_window.console.log('Playing '+s_id+' sound'); // Useful when debugging sounds when testing using SU, otherwise you don't know which window they came from
}
window.top_window.soundManager.play(s_id);
}
function chat_load(room_id)
{
window.top_window=window;
try
{
document.getElementById('post').focus();
}
catch (e) {}
if (window.location.href.indexOf('keep_chattest')==-1) begin_chatting(room_id);
window.text_colour=document.getElementById('text_colour');
if (window.text_colour) window.text_colour.style.color=text_colour.value;
manage_scroll_height(document.getElementById('post'));
}
function begin_chatting(room_id)
{
window.load_from_room_id=room_id;
if (typeof window.do_ajax_request!='undefined')
{
chat_check(true,0);
play_chat_sound('you_connect');
} else
{
window.setTimeout(begin_chatting,10);
}
}
function check_chat_options(ob)
{
if (!ob.elements['text_colour'].value.match(/^#[0-9A-F][0-9A-F][0-9A-F]([0-9A-F][0-9A-F][0-9A-F])?$/))
{
window.fauxmodal_alert('{!chat:BAD_HTML_COLOUR;^}');
return false;
}
return check_form(ob);
}
function dec_to_hex(number)
{
var hexbase='0123456789ABCDEF';
return hexbase.charAt((number>>4)&0xf)+hexbase.charAt(number&0xf);
}
function hex_to_dec(number)
{
return parseInt(number,16);
}
function update_picker_colour()
{
}
function chat_on_rgb_change(o)
{
var value='#'+dec_to_hex(o.newValue[0])+dec_to_hex(o.newValue[1])+dec_to_hex(o.newValue[2]);
window.text_colour.value=value;
window.text_colour.style.color=value;
document.getElementById('colour').value=value;
//document.getElementById('post').style.color=value;
}
function on_font_change(o)
{
var value=o.options[o.selectedIndex].value;
document.getElementById('font').value=value;
document.getElementById('post').style.fontFamily=value;
manage_scroll_height(document.getElementById('post'));
}
function get_ticked_people(form)
{
var people='';
for (var i=0;i
0)
{
message_container.insertBefore(cloned_message,message_container.childNodes[0]);
if (!first_set) // Only if no other message sound already for this event update
{
if (!skip_incoming_sound)
{
if (typeof window.play_chat_sound!='undefined') play_chat_sound(window.has_focus?'message_received':'message_background',messages[i].getAttribute('sender_id'));
}
flashable_alert=true;
}
} else // First message
{
set_inner_html(message_container,'');
message_container.appendChild(cloned_message);
first_set=true; // Let the code know the first set of messages has started, squashing any extra sounds for this event update
if (!skip_incoming_sound)
{
play_chat_sound('message_initial');
}
}
if (!message_container_global)
{
current_room_id=-1; // We'll be gathering for all rooms we're in now, because this messaging is coming through the master control window
}
}
else if (messages[i].nodeName=='chat_members_update') // UPDATE MEMBERS LIST IN ROOM
{
var members_element=document.getElementById('chat_members_update');
if (members_element) set_inner_html(members_element,merge_text_nodes(messages[i].childNodes));
}
else if ((messages[i].nodeName=='chat_event') && (typeof window.im_participant_template!='undefined')) // Some kind of transitory event
{
event_type=messages[i].getAttribute('event_type');
room_id=messages[i].getAttribute('room_id');
member_id=messages[i].getAttribute('member_id');
username=messages[i].getAttribute('username');
avatar_url=messages[i].getAttribute('avatar_url');
id=merge_text_nodes(messages[i].childNodes);
switch (event_type)
{
case 'BECOME_ACTIVE':
if (window.TRANSITORY_ALERT_TIME!=0)
{
flashable_alert=true;
tmp_element=document.getElementById('online_'+member_id);
if (tmp_element)
{
if (get_inner_html(tmp_element).toLowerCase()=='{!ACTIVE;^}'.toLowerCase()) break;
set_inner_html(tmp_element,'{!ACTIVE;^}');
var friend_img=document.getElementById('friend_img_'+member_id);
if (friend_img) friend_img.className='friend_active';
var alert_box_wrap=document.getElementById('alert_box_wrap');
if (alert_box_wrap) alert_box_wrap.style.display='block';
var alert_box=document.getElementById('alert_box');
if (alert_box) set_inner_html(alert_box,'{!NOW_ONLINE;^}'.replace('{'+'1}',username));
window.setTimeout(function() {
if (document.getElementById('alert_box')) // If the alert box is still there, remove it
alert_box_wrap.style.display='none';
} , window.TRANSITORY_ALERT_TIME);
if (!skip_incoming_sound)
{
play_chat_sound('contact_on',member_id);
}
} else if (!document.getElementById('chat_lobby_convos_tabs'))
{
create_overlay_event(/*skip_incoming_sound*/true,member_id,'{!NOW_ONLINE;^}'.replace('{'+'1}',username),function() { start_im(member_id,true); return false; } ,avatar_url);
}
}
rooms=find_im_convo_room_ids();
for (var r in rooms)
{
room_id=rooms[r];
var doc=document;
if ((typeof opened_popups['room_'+room_id]!='undefined') && (!opened_popups['room_'+room_id].is_shutdown))
{
if (!opened_popups['room_'+room_id].document) continue;
doc=opened_popups['room_'+room_id].document;
}
tmp_element=doc.getElementById('participant_online__'+room_id+'__'+member_id);
if (tmp_element)
{
set_inner_html(tmp_element,'{!ACTIVE;^}');
}
}
break;
case 'BECOME_INACTIVE':
var friend_being_tracked=false;
tmp_element=document.getElementById('online_'+member_id);
if (tmp_element)
{
if (get_inner_html(tmp_element).toLowerCase()=='{!INACTIVE;^}'.toLowerCase()) break;
set_inner_html(tmp_element,'{!INACTIVE;^}');
document.getElementById('friend_img_'+member_id).className='friend_inactive';
friend_being_tracked=true;
}
rooms=find_im_convo_room_ids();
for (var r in rooms)
{
room_id=rooms[r];
var doc=document;
if (typeof opened_popups['room_'+room_id]!='undefined')
{
if (!opened_popups['room_'+room_id].document) continue;
doc=opened_popups['room_'+room_id].document;
}
tmp_element=doc.getElementById('participant_online__'+room_id+'__'+member_id);
if (tmp_element) set_inner_html(tmp_element,'{!INACTIVE;^}');
friend_being_tracked=true;
}
if (!skip_incoming_sound)
{
if (friend_being_tracked)
play_chat_sound('contact_off',member_id);
}
break;
case 'JOIN_IM':
add_im_member(room_id,member_id,username,messages[i].getAttribute('away')=='1',avatar_url);
var doc=document;
if ((typeof opened_popups['room_'+room_id]!='undefined') && (!opened_popups['room_'+room_id].is_shutdown))
{
if (!opened_popups['room_'+room_id].document) break;
doc=opened_popups['room_'+room_id].document;
}
tmp_element=doc.getElementById('participant_online__'+room_id+'__'+member_id);
if (tmp_element)
{
if (get_inner_html(tmp_element).toLowerCase()=='{!ACTIVE;^}'.toLowerCase()) break;
set_inner_html(tmp_element,'{!ACTIVE;^}');
document.getElementById('friend_img_'+member_id).className='friend_active';
}
if (!skip_incoming_sound)
{
play_chat_sound('contact_on',member_id);
}
break;
case 'PREINVITED_TO_IM':
add_im_member(room_id,member_id,username,messages[i].getAttribute('away')=='1',avatar_url);
break;
case 'DEINVOLVE_IM':
var doc=document;
if (typeof opened_popups['room_'+room_id]!='undefined')
{
if (!opened_popups['room_'+room_id].document) break;
doc=opened_popups['room_'+room_id].document;
}
tmp_element=doc.getElementById('participant__'+room_id+'__'+member_id);
if ((tmp_element) && (tmp_element.parentNode))
{
var parent=tmp_element.parentNode;
/*Actually prefer to let them go away it's cleaner if (parent.childNodes.length==1) // Don't really let them go, flag them merely as away - we'll reinvite them upon next post
{
tmp_element=doc.getElementById('post_'+room_id);
if (tmp_element) tmp_element.force_invite=member_id;
tmp_element=doc.getElementById('participant_online__'+room_id+'__'+member_id);
if (tmp_element)
{
if (get_inner_html(tmp_element).toLowerCase()=='{!INACTIVE;^}'.toLowerCase()) break;
set_inner_html(tmp_element,'{!INACTIVE;^}');
}
} else*/
{
parent.removeChild(tmp_element);
}
/*if (parent.childNodes.length==0) Don't set to none, as we want to allow the 'force_invite' IM re-activation feature, to draw the other guy back -- above we pretended they're merely 'away', not just left
{
set_inner_html(parent,'{!NONE;^}');
}*/
if (!skip_incoming_sound)
{
play_chat_sound('contact_off',member_id);
}
}
break;
}
} else // INVITES
if ((messages[i].nodeName=='chat_invite') && (typeof window.im_participant_template!='undefined'))
{
room_id=merge_text_nodes(messages[i].childNodes);
if ((!document.getElementById('room_'+room_id)) && ((typeof opened_popups['room_'+room_id]=='undefined') || (opened_popups['room_'+room_id].is_shutdown)))
{
room_name=messages[i].getAttribute('room_name');
avatar_url=messages[i].getAttribute('avatar_url');
participants=messages[i].getAttribute('participants');
var is_new=(messages[i].getAttribute('num_posts')=='0');
var by_you=(messages[i].getAttribute('inviter')==messages[i].getAttribute('you'));
if ((!by_you) && (!window.instant_go) && (!document.getElementById('chat_lobby_convos_tabs')))
{
create_overlay_event(skip_incoming_sound,messages[i].getAttribute('inviter'),'{!IM_INFO_CHAT_WITH;^}'.replace('{'+'1}',room_name),function() { window.last_message_id=-1 /*Ensure messages re-processed*/; detected_conversation(room_id,room_name,participants); return false; } ,avatar_url,room_id);
} else
{
detected_conversation(room_id,room_name,participants);
}
flashable_alert=true;
}
} else
if (messages[i].nodeName=='chat_tracking') // TRACKING
{
window.top_window.last_message_id=messages[i].getAttribute('last_msg');
window.top_window.last_event_id=messages[i].getAttribute('last_event');
}
}
// Get attention, to indicate something has happened
if (flashable_alert)
{
if ((room_id) && (typeof opened_popups['room_'+room_id]!='undefined') && (!opened_popups['room_'+room_id].is_shutdown))
{
if (typeof opened_popups['room_'+room_id].getAttention!='undefined') opened_popups['room_'+room_id].getAttention();
if (typeof opened_popups['room_'+room_id].focus!='undefined')
{
try
{
opened_popups['room_'+room_id].focus();
}
catch (e) {}
}
if (opened_popups['room_'+room_id].document)
{
var post=opened_popups['room_'+room_id].document.getElementById('post');
if (post)
{
try
{
post.focus();
}
catch (e) {}
}
}
} else
{
if (typeof window.getAttention!='undefined') window.getAttention();
if (typeof window.focus!='undefined')
{
try
{
window.focus();
}
catch (e) {}
}
var post=document.getElementById('post');
if (post && post.name=='message'/*The chat posting field is named message and IDd post*/)
{
try
{
post.focus();
}
catch (e) {}
}
}
}
if (window.top_window.last_timestamp {!LOADING;^}<\/span><\/div><\/div>');
}
}
var element,participants=null;
var tabs=document.getElementById('chat_lobby_convos_tabs');
if (tabs)
{
element=document.getElementById('room_'+room_id);
if (!element) return; // Probably already been clicked once, lag
var tab_element=document.getElementById('tab_'+room_id);
element.style.display='none';
tab_element.style.display='none';
participants=tab_element.participants;
} else
{
if (is_popup)
participants=((typeof window.already_autonomous!='undefined') && (window.already_autonomous))?window.participants:window.top_window.opened_popups['room_'+room_id].participants;
}
window.top_window.already_received_room_invites[room_id]=false;
if (is_popup) window.is_shutdown=true;
window.setTimeout(function() // Give time for any logs to download (download does not need to have finished - but must have loaded into a request response on the server side)
{
window.top_window.do_ajax_request('{$FIND_SCRIPT;,messages}?action=deinvolve_im'+window.top_window.keep_stub(false),function() {},'room_id='+window.encodeURIComponent(room_id)); // Has to be on top_window or it will be lost if the window was explicitly closed (it is unloading mode and doesn't want to make a new request)
if (participants)
window.top_window.all_conversations[participants]=null;
if (tabs)
{
if ((element) && (element.parentNode)) element.parentNode.removeChild(element);
if (!tab_element.parentNode) return;
tab_element.parentNode.removeChild(tab_element);
// All gone?
var count=count_im_convos();
if (count==0)
{
set_inner_html(tabs,' ');
document.getElementById('chat_lobby_convos_tabs').style.display='none';
set_inner_html(document.getElementById('chat_lobby_convos_areas'),no_im_html);
if (document.getElementById('invite_ongoing_im_button')) document.getElementById('invite_ongoing_im_button').disabled=true;
} else
{
chat_select_tab(document.getElementById('tab_'+find_im_convo_room_ids().pop()));
}
} else if (is_popup)
{
window.onbeforeunload=null;
window.close();
}
}, logs?window.LOGS_DOWNLOAD_INTERVAL:10);
}
function detected_conversation(room_id,room_name,participants) // Assumes conversation is new: something must check that before calling here
{
window.top_window.last_event_id=-1; // So that invite events re-run
var areas=document.getElementById('chat_lobby_convos_areas');
var tabs=document.getElementById('chat_lobby_convos_tabs');
var lobby;
if (tabs) // Chat lobby
{
tabs.style.display='block';
if (document.getElementById('invite_ongoing_im_button')) document.getElementById('invite_ongoing_im_button').disabled=false;
var count=count_im_convos();
// First one?
if (count==0)
{
window.no_im_html=get_inner_html(areas);
set_inner_html(areas,'');
set_inner_html(tabs,'');
}
lobby=true;
} else // Not chat lobby (sitewide IM)
{
lobby=false;
}
window.top_window.all_conversations[participants]=room_id;
var url='{$FIND_SCRIPT_NOHTTP;,messages}?action=join_im&event_id='+window.top_window.last_event_id+window.top_window.keep_stub(false);
var post='room_id='+window.encodeURIComponent(room_id);
// Add in
var new_one=window.im_area_template.replace(/\_\_room_id\_\_/g,room_id).replace(/\_\_room\_name\_\_/g,room_name);
if (lobby)
{
var new_div;
new_div=document.createElement('div');
set_inner_html(new_div,new_one);
areas.appendChild(new_div);
// Add tab
new_div=document.createElement('div');
new_div.className='chat_lobby_convos_tab_uptodate'+((count==0)?' chat_lobby_convos_tab_first':'');
set_inner_html(new_div,escape_html(room_name));
new_div.setAttribute('id','tab_'+room_id);
new_div.participants=participants;
new_div.onclick=function() { chat_select_tab(new_div); } ;
tabs.appendChild(new_div);
chat_select_tab(new_div);
// Tell server we've joined
do_ajax_request(url,function(ajax_result_frame,ajax_result) { process_chat_xml_messages(ajax_result,true); },post);
} else
{
// Open popup
var im_popup_window_options='width=370,height=460,menubar=no,toolbar=no,location=no,resizable=no,scrollbars=yes,top='+((screen.height-520)/2)+',left='+((screen.width-440)/2);
var new_window=window.open('{$BASE_URL;,0}'.replace(/^https?:/,window.location.protocol)+'/data/empty.html?instant_messaging','room_'+room_id,im_popup_window_options); // The "?instant_messaging" is just to make the location bar less surprising to the user ;-) [modern browsers always show the location bar for security, even if we try and disable it]
if ((!new_window) || (typeof new_window.window=='undefined' /*BetterPopupBlocker for Chrome returns a fake new window but won't have this defined in it*/))
{
fauxmodal_alert('{!chat:_FAILED_TO_OPEN_POPUP;,{$PAGE_LINK*,_SEARCH:popup_blockers:failure=1,0,1}}',null,'{!chat:FAILED_TO_OPEN_POPUP;^}',true);
}
window.setTimeout(function() // Needed for Safari to set the right domain, and also to give window an opportunity to attach itself on its own accord
{
if ((typeof opened_popups['room_'+room_id]!='undefined') && (opened_popups['room_'+room_id]!=null) && (!opened_popups['room_'+room_id].is_shutdown)) // It's been reattached already
{
return;
}
opened_popups['room_'+room_id]=new_window;
if ((new_window) && (typeof new_window.document!='undefined'))
{
new_window.document.open();
new_window.document.write(new_one); // This causes a blocking on Firefox while files download/parse. It's annoying, you'll see the popup freezes. But it works after a few seconds.
new_window.document.close();
new_window.top_window=window;
new_window.room_id=room_id;
new_window.load_from_room_id=-1;
window.setTimeout(function() // Allow XHTML to render; needed for .document to be available, which is needed to write in seeded chat messages
{
if (!new_window.document) return;
new_window.participants=participants;
new_window.onbeforeunload=function() {
return '{!CLOSE_VIA_END_CHAT_BUTTON;^}';
//new_window.close_chat_conversation(room_id);
};
try
{
new_window.focus();
}
catch (e) {}
// Tell server we have joined
do_ajax_request(url,function(ajax_result_frame,ajax_result) { process_chat_xml_messages(ajax_result,true); },post);
// Set title
var dom_title=new_window.document.getElementsByTagName('title')[0];
if (dom_title!=null)
new_window.document.title=get_inner_html(dom_title).replace(/<.*?>/g,''); // For Safari
},500); /* Could be 60 except for Firefox which is slow */
}
},60);
}
}
function add_im_member(room_id,member_id,username,away,avatar_url)
{
window.setTimeout(function() {
var doc=document;
if (typeof opened_popups['room_'+room_id]!='undefined')
{
if (opened_popups['room_'+room_id].is_shutdown) return;
if (!opened_popups['room_'+room_id].document) return;
doc=opened_popups['room_'+room_id].document;
}
if (away)
{
var tmp_element=doc.getElementById('online_'+member_id);
if ((tmp_element) && (get_inner_html(tmp_element).toLowerCase()=='{!ACTIVE;^}'.toLowerCase())) away=false;
}
if (doc.getElementById('participant__'+room_id+'__'+member_id)) return; // They're already put in it
var new_participant=doc.createElement('div');
var new_participant_inner=window.im_participant_template.replace(/\_\_username\_\_/g,username);
new_participant_inner=new_participant_inner.replace(/\_\_id\_\_/g,member_id);
new_participant_inner=new_participant_inner.replace(/\_\_room\_id\_\_/g,room_id);
new_participant_inner=new_participant_inner.replace(/\_\_avatar\_url\_\_/g,avatar_url);
if (avatar_url=='') new_participant_inner=new_participant_inner.replace('style="display: block" id="avatar__','style="display: none" id="avatar__');
new_participant_inner=new_participant_inner.replace(/\_\_online\_\_/g,away?'{!INACTIVE;^}':'{!ACTIVE;^}');
set_inner_html(new_participant,new_participant_inner);
new_participant.setAttribute('id','participant__'+room_id+'__'+member_id);
var element=doc.getElementById('participants__'+room_id);
if (element) // If we've actually got the HTML for the room setup
{
var p_list=get_inner_html(element).toLowerCase();
if ((p_list.indexOf('')!=-1) || (p_list.indexOf('')!=-1))
set_inner_html(element,'');
element.appendChild(new_participant);
if (doc.getElementById('friend_img_'+member_id)) doc.getElementById('friend__'+member_id).style.display='none';
}
}, 0);
}
function find_current_im_room()
{
var chat_lobby_convos_tabs=document.getElementById('chat_lobby_convos_tabs');
if (!chat_lobby_convos_tabs) return window.room_id;
for (var i=0;i