src/js/supportchat.js

changeset 48
12b42931151a
parent 47
6985de83d146
child 49
6d46d2518705
equal deleted inserted replaced
47:6985de83d146 48:12b42931151a
1 /* Config */
2
3 var support_config = {
4 login_domain: "anon.localhost",
5 bosh_url: "/http-bind",
6 muc_server: "support.localhost",
7 team_rooms: {
8 "Sales": "sales@support.localhost",
9 "Technical": "technical@support.localhost"
10 },
11 send_invites: true,
12 offline_support: "support@localhost",
13 alternative_url: "http://www.google.co.uk/"
14 };
15
16 /*** XMPP handling */
17 var conn = null;
18
19 /*** Query information */
20 var question_type; // E.g. "Sales", "Technical"
21 var question_name; // Name of the submitter
22 var question_text; // The query itself
23
24 /* Called by Strophe when status of connection changes
25 (from disconnected to connected, vice-versa, etc.)
26 */
27 function handle_connection_status(status, err)
28 {
29 if(err)
30 set_ui_state("error");
31 }
32
33 /* Initiate the connection to the XMPP server */
34 function start_connection()
35 {
36 conn = new Strophe.Connection(support_config.bosh_url);
37 var ret = true;
38 try
39 {
40 conn.connect(support_config.login_domain, null, handle_connection_status, 50);
41 }
42 catch(e)
43 {
44 ret = false;
45 }
46 return ret;
47 }
48
49 /*** UI handling */
50
51 /* Initial UI state */
52 var ui_state = "question";
53
54 /* Called to change the UI state (question, wait, converse) */
55 function set_ui_state(new_state)
56 {
57 if(ui_state != new_state)
58 {
59 $("#support-"+ui_state).hide();
60 $("#support-"+(ui_state=new_state)).show();
61 }
62 }
63
64 /* Handle the user submitting the question form */
65 function on_question_submit()
66 {
67 question_type = $("#support-question-type").val();
68 question_name = $("#support-question-name").val();
69 question_text = $("#support-question-text").val();
70
71 var our_nick = question_name;
72
73 set_ui_state("wait");
74
75 // Create our question room
76 var question_muc = new MUC(conn, {
77 // Handle room joins
78 joined: function (stanza, muc, occupant)
79 {
80 if(occupant.nick == our_nick)
81 // We joined the question room, now join the team room and tell them
82 team_muc.join(support_config.team_rooms[question_type], our_nick);
83 else if(ui_state == "wait")
84 {
85 // We were waiting for an assistant, and one just joined
86 var html = "<span class='muc-message'><span class='muc-nick'>" + htmlescape(occupant.nick) + "</span>" + " is answering your query</span><br/>\n";
87 $("#support-log").append(html).scrollTop($("#support-log")[0].scrollHeight);
88 $("#support-send-button").click(function ()
89 {
90 question_muc.send_message($("#support-input").val());
91 $("#support-input").val("");
92 });
93 set_ui_state("converse");
94 }
95 },
96
97 // Handle incoming messages
98 message: function (stanza, muc, nick, message)
99 {
100 var html = "<span class='muc-message'><span class='muc-nick'>" + htmlescape(nick) + "</span>" + ": " + htmlescape(message) + "</span><br/>\n";
101 $("#support-log").append(html).scrollTop($("#support-log")[0].scrollHeight);
102 }
103 });
104
105 // Get a unique room name from the server and then join the question MUC
106 conn.sendIQ($iq({to: support_config.muc_server, type: "get"})
107 .c("query", { xmlns: "http://jabber.org/protocol/muc#unique" }),
108 function (result) // Success
109 {
110 var unique = Strophe.getText(result.getElementsByTagName("unique")[0]);
111 question_muc.join(unique + "@" + support_config.muc_server, our_nick);
112 },
113 function (result) // Failure to get unique room name
114 {
115 var unique = "support-"+Math.floor(Math.random()*512);
116 question_muc.join(unique + "@" + support_config.muc_server, our_nick);
117 });
118
119 // Create the team MUC object (it will be joined after we join the question MUC)
120 var team_muc = new MUC(conn, {
121 // Someone joined the team MUC
122 joined: function (stanza, muc, occupant)
123 {
124 if(occupant.nick != our_nick)
125 return;
126
127 var sent = false;
128 for(var nick in team_muc.occupants)
129 {
130 if(team_muc.occupants[nick].affiliation == "none" || nick == our_nick)
131 continue;
132 sent = true;
133 if(support_config.send_invites)
134 team_muc.send_invite(team_muc.jid+"/"+nick, question_text + "\n" + question_muc.jid);
135 else
136 team_muc.send_private_message(nick, question_text + "\n" + question_muc.jid);
137 }
138 if(!sent)
139 {
140 set_ui_state("offline");
141 }
142 },
143
144 error: function (stanza, muc, error)
145 {
146 if(error == "conflict")
147 {
148 our_nick += "_";
149 muc.join(support_config.team_rooms[question_type], our_nick);
150 }
151 else
152 set_ui_state("error");
153 }
154 });
155 }
156
157 function build_ui()
158 {
159 return $(" \
160 <div id='support-chat'> \
161 <div id='support-question'> \
162 <h2>What is the nature of your question?</h2> \
163 <select id='support-question-type'> \
164 <option>Sales</option> \
165 <option>Technical</option> \
166 </select> \
167 <h2>What is your name?</h2> \
168 <input id='support-question-name' type='text' /> \
169 <h2>Your question:</h2> \
170 <textarea id='support-question-text'></textarea><br/> \
171 <input id='support-question-submit' type='submit' /> \
172 </div> \
173 <div id='support-wait'> \
174 Please wait while we find someone to \
175 answer your query... \
176 <br/><br/><br/><br/> \
177 <center><img src='waiting.gif' alt='Waiting' /></center> \
178 </div> \
179 <div id='support-converse'> \
180 <div id='support-log'></div> \
181 <div id='support-input-container'><textarea id='support-input' type='text' value=''></textarea></div> \
182 <input id='support-send-button' type='submit' value='Send' /> \
183 <div style='clear:right;'></div> \
184 </div> \
185 <div id='support-offline'> \
186 <p>Sorry, there are no assistants available \
187 to answer your question at the moment. \
188 </p> \
189 <div id='support-offline-form'> \
190 <p>To receive a reply to your question via \
191 email, please enter your email address \
192 below: \
193 </p> \
194 <input id='support-offline-email' type='text' /> \
195 <input id='support-offline-submit-button' type='submit' value='Submit' /> \
196 </div> \
197 <div id='support-offline-thanks'> \
198 <p>Thank you. Your question has been submitted \
199 and will be replied to as soon as an assistant \
200 becomes available.</p> \
201 </div> \
202 </div> \
203 <div id='support-error'> \
204 <p>Sorry, there is a problem with the live support \
205 service at the moment. Please see our \
206 <a href='"+support_config.alternative_url+"'>alternative \
207 support channels</a> to receive assistance. \
208 </p> \
209 </div> \
210 </div> \
211 ");
212 }
213
214 function display_ui()
215 {
216 // Display pop-up, showing question form
217 var ui = build_ui();
218
219 ui.appendTo("body");
220
221 $("#support-question-submit").click(on_question_submit);
222 $("#support-offline-submit-button").click(function ()
223 {
224 $("#support-offline-form").hide();
225 conn.send($msg({to: support_config.offline_support, type: "normal"})
226 .c("subject").t("Support query from " + question_name).up()
227 .c("body").t(question_text + "\n\nReply via email to: "+
228 $("#support-offline-email").val()));
229 $("#support-offline-thanks").show();
230 });
231
232 ui.dialog({
233 title:"Live Support",
234 height: 400,
235 width: 285
236 });
237
238 if(!start_connection())
239 {
240 set_ui_state("error");
241 }
242 }
243
244 /*** Helper functions */
245 function htmlescape(s)
246 {
247 return s.replace(/&/g,'&amp;').
248 replace(/>/g,'&gt;').
249 replace(/</g,'&lt;').
250 replace(/"/g,'&quot;');
251 }
252
253 function activate_links()
254 {
255 $("[href='#support-chat']").click(display_ui);
256 }
257
258 $(activate_links);

mercurial