Mon, 05 Apr 2010 13:18:24 +0100
xmpp_muc.js: Prepare occupant object with nick, status, role and affiliation
/* Config */ var support_config = { login_domain: "anon.localhost", bosh_url: "/http-bind", muc_server: "support.localhost", team_rooms: { "Sales": "sales@support.localhost", "Technical": "technical@support.localhost" }, send_invites: true, offline_support: "support@localhost", alternative_url: "http://www.google.co.uk/" }; /*** XMPP handling */ var conn = null; /*** Query information */ var question_type; // E.g. "Sales", "Technical" var question_name; // Name of the submitter var question_text; // The query itself /* Called by Strophe when status of connection changes (from disconnected to connected, vice-versa, etc.) */ function handle_connection_status(status, err) { if(err) set_ui_state("error"); } /* Initiate the connection to the XMPP server */ function start_connection() { conn = new Strophe.Connection(support_config.bosh_url); var ret = true; try { conn.connect(support_config.login_domain, null, handle_connection_status, 50); } catch(e) { ret = false; } return ret; } /*** UI handling */ /* Initial UI state */ var ui_state = "question"; /* Called to change the UI state (question, wait, converse) */ function set_ui_state(new_state) { if(ui_state != new_state) { $("#support-"+ui_state).hide(); $("#support-"+(ui_state=new_state)).show(); } } /* Handle the user submitting the question form */ function on_question_submit() { question_type = $("#support-question-type").val(); question_name = $("#support-question-name").val(); question_text = $("#support-question-text").val(); var our_nick = question_name; set_ui_state("wait"); // Create our question room var question_muc = new MUC(conn, { // Handle room joins joined: function (stanza, muc, nick) { if(nick == our_nick) // We joined the question room, now join the team room and tell them team_muc.join(support_config.team_rooms[question_type], our_nick); else if(ui_state == "wait") { // We were waiting for an assistant, and one just joined var html = "<span class='muc-message'><span class='muc-nick'>" + htmlescape(nick) + "</span>" + " is answering your query</span><br/>\n"; $("#support-log").append(html).scrollTop($("#support-log")[0].scrollHeight); $("#support-send-button").click(function () { question_muc.send_message($("#support-input").val()); $("#support-input").val(""); }); set_ui_state("converse"); } }, // Handle incoming messages message: function (stanza, muc, nick, message) { var html = "<span class='muc-message'><span class='muc-nick'>" + htmlescape(nick) + "</span>" + ": " + htmlescape(message) + "</span><br/>\n"; $("#support-log").append(html).scrollTop($("#support-log")[0].scrollHeight); } }); // Get a unique room name from the server and then join the question MUC conn.sendIQ($iq({to: support_config.muc_server, type: "get"}) .c("query", { xmlns: "http://jabber.org/protocol/muc#unique" }), function (result) // Success { var unique = Strophe.getText(result.getElementsByTagName("unique")[0]); question_muc.join(unique + "@" + support_config.muc_server, our_nick); }, function (result) // Failure to get unique room name { var unique = "support-"+Math.floor(Math.random()*512); question_muc.join(unique + "@" + support_config.muc_server, our_nick); }); // Create the team MUC object (it will be joined after we join the question MUC) var team_muc = new MUC(conn, { // Someone joined the team MUC joined: function (stanza, muc, nick) { if(nick != our_nick) return; var sent = false; for(var nick in team_muc.occupants) { var affiliation = $(stanza) .find("x[xmlns='http://jabber.org/protocol/muc#user']>item") .attr("affiliation"); if(affiliation == "none" || nick == our_nick) continue; sent = true; if(support_config.send_invites) team_muc.send_invite(team_muc.jid+"/"+nick, question_text + "\n" + question_muc.jid); else team_muc.send_private_message(nick, question_text + "\n" + question_muc.jid); } if(!sent) { set_ui_state("offline"); } }, error: function (stanza, muc, error) { if(error == "conflict") { our_nick += "_"; muc.join(support_config.team_rooms[question_type], our_nick); } else set_ui_state("error"); } }); } function build_ui() { return $(" \ <div id='support-chat'> \ <div id='support-question'> \ <h2>What is the nature of your question?</h2> \ <select id='support-question-type'> \ <option>Sales</option> \ <option>Technical</option> \ </select> \ <h2>What is your name?</h2> \ <input id='support-question-name' type='text' /> \ <h2>Your question:</h2> \ <textarea id='support-question-text'></textarea><br/> \ <input id='support-question-submit' type='submit' /> \ </div> \ <div id='support-wait'> \ Please wait while we find someone to \ answer your query... \ <br/><br/><br/><br/> \ <center><img src='waiting.gif' alt='Waiting' /></center> \ </div> \ <div id='support-converse'> \ <div id='support-log'></div> \ <div id='support-input-container'><textarea id='support-input' type='text' value=''></textarea></div> \ <input id='support-send-button' type='submit' value='Send' /> \ <div style='clear:right;'></div> \ </div> \ <div id='support-offline'> \ <p>Sorry, there are no assistants available \ to answer your question at the moment. \ </p> \ <div id='support-offline-form'> \ <p>To receive a reply to your question via \ email, please enter your email address \ below: \ </p> \ <input id='support-offline-email' type='text' /> \ <input id='support-offline-submit-button' type='submit' value='Submit' /> \ </div> \ <div id='support-offline-thanks'> \ <p>Thank you. Your question has been submitted \ and will be replied to as soon as an assistant \ becomes available.</p> \ </div> \ </div> \ <div id='support-error'> \ <p>Sorry, there is a problem with the live support \ service at the moment. Please see our \ <a href='"+support_config.alternative_url+"'>alternative \ support channels</a> to receive assistance. \ </p> \ </div> \ </div> \ "); } function display_ui() { // Display pop-up, showing question form var ui = build_ui(); ui.appendTo("body"); $("#support-question-submit").click(on_question_submit); $("#support-offline-submit-button").click(function () { $("#support-offline-form").hide(); conn.send($msg({to: support_config.offline_support, type: "normal"}) .c("subject").t("Support query from " + question_name).up() .c("body").t(question_text + "\n\nReply via email to: "+ $("#support-offline-email").val())); $("#support-offline-thanks").show(); }); ui.dialog({ title:"Live Support", height: 400, width: 285 }); if(!start_connection()) { set_ui_state("error"); } } /*** Helper functions */ function htmlescape(s) { return s.replace(/&/g,'&'). replace(/>/g,'>'). replace(/</g,'<'). replace(/"/g,'"'); } function activate_links() { $("[href='#support-chat']").click(display_ui); } $(activate_links);