"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;i0) { 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;^} {!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