corrade-http-templates – Diff between revs 43 and 44

Subversion Repositories:
Rev:
Only display areas with differencesIgnore whitespace
Rev 43 Rev 44
1 <!DOCTYPE html> 1 <!DOCTYPE html>
2 <html lang="en"> 2 <html lang="en">
3   3  
4 <head> 4 <head>
5 <title>Corrade Instant Message Template</title> 5 <title>Corrade Instant Message Template</title>
6 6
7 <meta charset="utf-8"> 7 <meta charset="utf-8">
8 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 8 <meta http-equiv="X-UA-Compatible" content="IE=edge">
9 <meta name="viewport" content="width=device-width, initial-scale=1"> 9 <meta name="viewport" content="width=device-width, initial-scale=1">
10 <meta name="description" content="Group Chat Relay using Corrade"> 10 <meta name="description" content="Group Chat Relay using Corrade">
11 <meta name="author" content="Wizardry and Steamworks"> 11 <meta name="author" content="Wizardry and Steamworks">
12 <link rel="icon" href="favicon.ico"> 12 <link rel="icon" href="favicon.ico">
13   -  
14 <link rel="stylesheet" href="css/style.css?v=2.0"> -  
15   13  
16 <!-- Bootstrap core CSS --> 14 <!-- Bootstrap core CSS -->
17 <link href="bower_components/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet"> 15 <link href="bower_components/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">
18 <!-- jQuery UI CSS --> 16 <!-- jQuery UI CSS -->
19 <link href="bower_components/jquery-ui/themes/base/jquery-ui.min.css" rel="stylesheet"> 17 <link href="bower_components/jquery-ui/themes/base/jquery-ui.min.css" rel="stylesheet">
20 <!-- <link rel="stylesheet" href="css/style.css?v=1.3"> --> -  
21 </head> 18 </head>
22   19  
23 <body> 20 <body>
24 21
25 <!-- Modal --> 22 <!-- Modal -->
26 <div id="dialog" class="modal fade" role="dialog"> 23 <div id="dialog" class="modal fade" role="dialog">
27 <div class="modal-dialog"> 24 <div class="modal-dialog">
28   25  
29 <!-- Modal content--> 26 <!-- Modal content-->
30 <div class="modal-content"> 27 <div class="modal-content">
31 <div class="modal-header"> 28 <div class="modal-header">
32 <button type="button" class="close" data-dismiss="modal">&times;</button> 29 <button type="button" class="close" data-dismiss="modal">&times;</button>
33 <h4 class="modal-title">Enter Agent Name</h4> 30 <h2 class="modal-title">Enter Agent Name</h2>
34 </div> 31 </div>
35 <form role="form" data-toggle="validator" class="form-inline"> 32 <form role="form" data-toggle="validator" class="form-inline">
36 <div class="modal-body"> 33 <div class="modal-body">
37 34
38 <div class="form-group"> 35 <div class="form-group">
39 <div class="input-group"> 36 <div class="input-group">
40 <label for="firstname">First Name</label> 37 <label for="firstname">First Name</label>
41 <input class="form-control" maxlength="8" type="text" id="firstname" placeholder="Corrade" required> 38 <input class="form-control" maxlength="8" type="text" id="firstname" placeholder="Corrade" required>
42 </div> 39 </div>
43 <div class="input-group"> 40 <div class="input-group">
44 <label for="lastname">Last Name</label> 41 <label for="lastname">Last Name</label>
45 <input class="form-control" maxlength="8" type="text" id="lastname" placeholder="Resident" required> 42 <input class="form-control" maxlength="8" type="text" id="lastname" placeholder="Resident" required>
46 </div> 43 </div>
47 </div> 44 </div>
48 45
49 46
50 </div> 47 </div>
51 <div class="modal-footer"> 48 <div class="modal-footer">
52 <button type="button" id="startConversation" class="btn btn-primary btn-lg"> 49 <button type="button" id="startConversation" class="btn btn-primary btn-lg">
53 <span class="glyphicon glyphicon-bullhorn" aria-hidden="true"></span> Start 50 <span class="glyphicon glyphicon-bullhorn" aria-hidden="true"></span> Start
54 </button> 51 </button>
55 <button type="button" class="btn btn-default" data-dismiss="modal">Close</button> 52 <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
56 </div> 53 </div>
57 </form> 54 </form>
58 </div> 55 </div>
59   56  
60 </div> 57 </div>
61 </div> 58 </div>
62 59  
63 <!-- <div id="dialog" title="Agent Name"> -  
64 <form> -  
65 <fieldset class="ui-helper-reset"> -  
66 <label for="firstname">Firstname</label> -  
67 <input type="text" name="firstname" id="firstname" value="" class="ui-widget-content ui-corner-all"> -  
68 <label for="lastname">Lastname</label> -  
69 <input type="text" name="lastname" id="lastname" value="" class="ui-widget-content ui-corner-all"> -  
70 </fieldset> -  
71 </form> -  
72 </div> --> -  
73 -  
74 <!-- <p> -  
75 Your name: <input type="text" size="8" value="Someone" id="name"></input> -  
76 <button id="add_tab">New Conversation</button> -  
77 </p> --> -  
78 -  
79 <div class="container"> 60 <div class="container">
80 <form role="form" data-toggle="validator"> 61 <form role="form" data-toggle="validator" action="javascript:return;">
81 <div class="form-group row"> 62 <div class="form-group row">
82 <div class="input-group"> 63 <div class="input-group">
83 <span class="input-group-addon"> 64 <span class="input-group-addon">
84 <label for="name">Your Name</label> 65 <label for="name">Your Name</label>
85 </span> 66 </span>
86 <input type="text" maxlength="8" value="Someone" id="name" class="form-control" required> 67 <input type="text" maxlength="8" value="Someone" id="name" class="form-control" required>
87 <span class="input-group-btn"> 68 <span class="input-group-btn">
88 <button type="button" id="add_tab" class="btn btn-default" data-toggle="modal" data-target="#dialog">New Tab</button> 69 <button type="submit" class="btn btn-default" data-toggle="modal" data-target="#dialog">New Conversation</button>
89 </span> 70 </span>
90 </div> 71 </div>
91 </div> 72 </div>
92 </form> 73 </form>
93 74
94 <!-- This div holds the tabs that will be created. This structure should not be deleted. --> 75 <!-- This div holds the tabs that will be created. This structure should not be deleted. -->
95 <!-- <ul class="nav nav-tabs" role="tablist" id="tabs"> -  
96 </ul> --> -  
97 <div id="tabs"> 76 <div id="tabs">
98 <ul> 77 <ul>
99   78  
100 </ul> 79 </ul>
101 <div> 80 <div>
102   81  
103 </div> 82 </div>
104 </div> 83 </div>
105 </div> 84 </div>
106 85
107 <!-- Include jQuery --> 86 <!-- Include jQuery -->
108 <script src="bower_components/jquery/dist/jquery.min.js"></script> 87 <script src="bower_components/jquery/dist/jquery.min.js"></script>
109 <!-- Include jQuery UI --> 88 <!-- Include jQuery UI -->
110 <script src="bower_components/jquery-ui/jquery-ui.min.js"></script> 89 <script src="bower_components/jquery-ui/jquery-ui.min.js"></script>
111 <!-- Include Bootstrap --> 90 <!-- Include Bootstrap -->
112 <script src="bower_components/bootstrap/dist/js/bootstrap.min.js"></script> 91 <script src="bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
113 <!-- Include Bootstrap Validator --> 92 <!-- Include Bootstrap Validator -->
114 <script src="bower_components/bootstrap-validator/js/validator.js"></script> 93 <script src="bower_components/bootstrap-validator/js/validator.js"></script>
115 <!-- Include Velocity --> 94 <!-- Include Velocity -->
116 <script src="bower_components/velocity/velocity.min.js"></script> 95 <script src="bower_components/velocity/velocity.min.js"></script>
117 96
118 <script> 97 <script>
119 $(function() { 98 $(function() {
120 var firstName = $("#firstname"), 99 var firstName = $("#firstname"),
121 lastName = $("#lastname"), 100 lastName = $("#lastname"),
-   101 tabTemplate = "<li id='#{id}'> \
-   102 <a href='#{href}'>#{label}</a> \
122 tabTemplate = "<li id='#{id}'><a href='#{href}'>#{label}</a> <span class='ui-icon ui-icon-close' role='presentation'>Remove Tab</span></li>", 103 <span class='ui-icon ui-icon-close'></span> \
-   104 </li>",
123 tabCounter = 0, 105 tabCounter = 0,
124 messageIntervals = {}, 106 messageIntervals = {},
125 getConversationsTimeout; 107 getConversationsTimeout,
126   -  
127 var tabs = $("#tabs").tabs() 108 tabs = $("#tabs").tabs();
128   -  
129 // Custom buttons and a "close" callback resetting the form inside. -  
130 /*var dialog = $("#dialog").dialog({ -  
131 autoOpen: false, -  
132 modal: true, -  
133 buttons: { -  
134 Add: function() { -  
135 addTab(); -  
136 $(this).dialog("close"); -  
137 }, -  
138 Cancel: function() { -  
139 $(this).dialog("close"); -  
140 } -  
141 }, -  
142 close: function() { -  
143 form[0].reset(); -  
144 } -  
145 }); -  
146   -  
147 // Calls addTab function on submit and closes the dialog. -  
148 var form = dialog.find("form").on("submit", function(event) { -  
149 addTab(); -  
150 dialog.dialog("close"); -  
151 event.preventDefault(); -  
152 }); -  
153 -  
154 // The add tab button just opens the dialog and prompts for the avatar name. -  
155 $("#add_tab") -  
156 .button() -  
157 .on("click", function() { -  
158 dialog.dialog("open"); -  
159 });*/ -  
160   109  
161 $("#startConversation") 110 $("#startConversation")
162 .on("click", function() { 111 .on("click", function() {
163 addTab(); 112 addTab();
164 $("#dialog").modal('hide'); 113 $("#dialog").modal('hide');
165 }); 114 });
166   115  
167 // Request the active conversations from the backend script and create tabs. 116 // Request the active conversations from the backend script and create tabs.
168 function getConversations() { 117 function getConversations() {
169 $.get("getConversations.php?t=" + Math.random(), function(data) { 118 $.get("getConversations.php?t=" + Math.random(), function(data) {
170 var json = $.parseJSON(data); 119 var json = $.parseJSON(data);
171 $.each(json, function(index, avatar) { 120 $.each(json, function(index, avatar) {
172 if (!conversationExists(avatar.firstname, avatar.lastname)) 121 if (!conversationExists(avatar.firstname, avatar.lastname))
173 addTab(avatar.firstname, avatar.lastname); 122 addTab(avatar.firstname, avatar.lastname);
174 }); 123 });
175 getConversationsTimeout = setTimeout( 124 getConversationsTimeout = setTimeout(
176 getConversations, 125 getConversations,
177 1000 126 1000
178 ); 127 );
179 }); 128 });
180 } 129 }
181   130  
182 // Function to send the message to an agent by passing it back through PHP. 131 // Function to send the message to an agent by passing it back through PHP.
183 function sendInstantMessage(e) { 132 function sendInstantMessage(e) {
184 var index = e.data.index; 133 var index = e.data.index;
185 // If the parameters are empty, then do not send anything to the PHP script. 134 // If the parameters are empty, then do not send anything to the PHP script.
186 if($.trim($("#firstname-" + index).val()) == '' || 135 if($.trim($("#firstname-" + index).val()) == '' ||
187 $.trim($("#lastname-" + index).val()) == '' || 136 $.trim($("#lastname-" + index).val()) == '' ||
188 $.trim($("#message-" + index).val()) == '') 137 $.trim($("#message-" + index).val()) == '')
189 return; 138 return;
190 $("#controls-" + index).animate({ 139 $("#controls-" + index).animate(
-   140 {
191 opacity: 'hide' 141 opacity: 0
-   142 },
-   143 {
-   144 duration: 1000,
-   145 easing: "linear"
-   146 }
192 }, 'slow'); 147 );
193 $.ajax({ 148 $.ajax({
194 type: 'post', 149 type: 'post',
195 url: "sendInstantMessage.php", 150 url: "sendInstantMessage.php",
196 data: { 151 data: {
197 name: $("#name").val(), 152 name: $("#name").val(),
198 firstname: $("#firstname-" + index).val(), 153 firstname: $("#firstname-" + index).val(),
199 lastname: $("#lastname-" + index).val(), 154 lastname: $("#lastname-" + index).val(),
200 message: $("#message-" + index).val() 155 message: $("#message-" + index).val()
201 } 156 }
202 }).done(function(data) { 157 }).done(function(data) {
203 if(data) 158 if(data)
204 alert(data); 159 alert(data);
205 $("#message-" + index).val(""); 160 $("#message-" + index).val("");
206 $("#controls-" + index).animate({ 161 $("#controls-" + index).animate(
-   162 {
207 opacity: 'show' 163 opacity: 1
-   164 },
-   165 {
-   166 duration: 1000,
-   167 easing: "linear"
-   168 }
208 }, 'slow'); 169 );
209 }); 170 });
210 } 171 }
211   172  
212 // Loads all the stored instant messages from the log file named after the avatar. 173 // Loads all the stored instant messages from the log file named after the avatar.
213 function loadInstantMessage(index) { 174 function loadInstantMessage(index) {
214 $.get("messages/" + $("#firstname-" + index).val() + " " + $("#lastname-" + index).val() + ".log" + "?t=" + Math.random(), function(data) { 175 $.get("messages/" + $("#firstname-" + index).val() + " " + $("#lastname-" + index).val() + ".log" + "?t=" + Math.random(), function(data) {
215 $("#chat-" + index).html(data); 176 $("#chat-" + index).html(data);
216 /*$("#chat-" + index).animate({ -  
217 scrollTop: $("#chat-" + index)[0].scrollHeight - $("#chat-" + index).height() -  
218 }, 1000);*/ -  
219 // Scroll to the bottom of the conversation. 177 // Scroll to the bottom of the conversation.
220 $("#chat-" + index).scrollTop($("#chat-" + index)[0].scrollHeight); 178 $("#chat-" + index).scrollTop($("#chat-" + index)[0].scrollHeight);
221 messageIntervals[index] = setTimeout( 179 messageIntervals[index] = setTimeout(
222 loadInstantMessage, 180 loadInstantMessage,
223 1000, 181 1000,
224 index 182 index
225 ); 183 );
226 }); 184 });
227 } 185 }
228   186  
229 // This function checks whether a conversation / tab already exists. 187 // This function checks whether a conversation / tab already exists.
230 function conversationExists(firstName, lastName) { 188 function conversationExists(firstName, lastName) {
231 var exists = false; 189 var exists = false;
232 for (var i = tabCounter; i >= 0; --i) { 190 for (var i = tabCounter; i >= 0; --i) {
233 if ($("#firstname-" + i).length && 191 if ($("#firstname-" + i).length &&
234 $("#firstname-" + i).val().toUpperCase() == firstName.toUpperCase() && 192 $("#firstname-" + i).val().toUpperCase() == firstName.toUpperCase() &&
235 $("#lastname-" + i).length && 193 $("#lastname-" + i).length &&
236 $("#lastname-" + i).val().toUpperCase() == lastName.toUpperCase()) { 194 $("#lastname-" + i).val().toUpperCase() == lastName.toUpperCase()) {
237 exists = true; 195 exists = true;
238 break; 196 break;
239 } 197 }
240 } 198 }
241 return exists; 199 return exists;
242 } 200 }
243   201  
244 // Adds a new tab in case a conversation with that agent does not exist. 202 // Adds a new tab in case a conversation with that agent does not exist.
245 function addTab(first, last) { 203 function addTab(first, last) {
246 var first = typeof first !== 'undefined' ? first : firstName.val(); 204 var first = typeof first !== 'undefined' ? first : firstName.val();
247 var last = typeof last !== 'undefined' ? last : lastName.val(); 205 var last = typeof last !== 'undefined' ? last : lastName.val();
248 206
249 // A conversation with that agent exists, so just do nothing. 207 // A conversation with that agent exists, so just do nothing.
250 if (conversationExists(first, last)) 208 if (conversationExists(first, last))
251 return; 209 return;
252 210
253 // Normalize avatar names by capitalizing the first letter of the firstname and the last name. 211 // Normalize avatar names by capitalizing the first letter of the firstname and the last name.
254 first = first.charAt(0).toUpperCase() + first.substr(1); 212 first = first.charAt(0).toUpperCase() + first.substr(1);
255 last = last.charAt(0).toUpperCase() + last.substr(1); 213 last = last.charAt(0).toUpperCase() + last.substr(1);
256 214
257 // Build the discussion form and add the tab. 215 // Build the discussion form and add the tab.
258 var label = first + " " + last, 216 var label = first + " " + last,
259 id = "tabs-" + tabCounter, 217 id = "tabs-" + tabCounter,
260 li = $(tabTemplate.replace(/#\{href\}/g, "#" + id).replace(/#\{id\}/g, tabCounter).replace(/#\{label\}/g, label)); 218 li = $(tabTemplate.replace(/#\{href\}/g, "#" + id).replace(/#\{id\}/g, tabCounter).replace(/#\{label\}/g, label));
261   219  
262 tabs.find(".ui-tabs-nav").append(li); 220 tabs.find(".ui-tabs-nav").append(li);
263 tabs.append("<div id='" + id + "'><p>" + " \ 221 tabs.append("<div id='" + id + "'>"+ " \
264 <div id='container-" + tabCounter + "'> \ 222 <div id='container-" + tabCounter + "'> \
-   223 <form role='form' data-toggle='validator' id='form-" + tabCounter + "' action='javascript:return;'> \
-   224 <div class='form-group row'> \
265 <textarea readonly='readonly' id='chat-" + tabCounter + "' rows='12'></textarea><br/> \ 225 <textarea class='form-control' readonly='readonly' id='chat-" + tabCounter + "' rows='12'></textarea><br/> \
-   226 </div> \
266 <div id='controls-" + tabCounter + "'> \ 227 <div id='controls-" + tabCounter + "' class='form-group row'> \
-   228 <div class='col-lg-1'> \
-   229 <div class='input-group'> \
-   230 <span class='input-group-addon'> \
-   231 <label for='message-" + tabCounter + "'>Message</label> \
-   232 </span> \
267 Message: <input type='text' size='70' id='message-" + tabCounter + "'></input> \ 233 <input type='text' maxlength='255' class='form-control' id='message-" + tabCounter + "' required> \
-   234 <span class='input-group-btn' style='font-size: inherit;'> \
268 <button type='button' id='send-" + tabCounter + "'>Send</button> \ 235 <button type='submit' class='btn btn-default' id='send-" + tabCounter + "'>Send</button> \
-   236 </span> \
-   237 </div> \
-   238 </div> \
-   239 </div> \
269 <input type='hidden' name='firstname' id='firstname-" + tabCounter + "' value='" + first + "'></input> \ 240 <input type='hidden' name='firstname' id='firstname-" + tabCounter + "' value='" + first + "'> \
270 <input type='hidden' name='lastname' id='lastname-" + tabCounter + "' value='" + last + "'></input> \ 241 <input type='hidden' name='lastname' id='lastname-" + tabCounter + "' value='" + last + "'> \
271 </div> \ 242 </form> \
272 </div> \ 243 </div> \
273 " + "</p></div>"); 244 </div>");
274 tabs.tabs("refresh"); 245 tabs.tabs("refresh");
-   246 $("#form-" + tabCounter).validator();
275   247  
276 // Subscribe to click event to send the instant message. 248 // Subscribe to click event to send the instant message.
277 $("#send-" + tabCounter).on("click", { 249 $("#send-" + tabCounter).on("click", {
278 index: tabCounter 250 index: tabCounter
279 }, sendInstantMessage); 251 }, sendInstantMessage);
280   252  
281 // Subscribe to pressing enter with the message input box selected. 253 // Subscribe to pressing enter with the message input box selected.
282 $("#message-" + tabCounter).keypress({ 254 $("#message-" + tabCounter).keypress({
283 index: tabCounter 255 index: tabCounter
284 }, function(e) { 256 }, function(e) {
285 if (e.which == 13) { 257 if (e.which == 13) {
286 sendInstantMessage(e); 258 sendInstantMessage(e);
287 return false; 259 return false;
288 } 260 }
289 }); 261 });
290   262  
291 ++tabCounter; 263 ++tabCounter;
292 } 264 }
293   265  
294 // Close icon: removing the tab on click and delete the conversation. 266 // Close icon: removing the tab on click and delete the conversation.
295 tabs.on("click", "span.ui-icon-close", function() { 267 tabs.on("click", "span.ui-icon-close", function() {
296 var panelId = $(this).closest("li").remove().attr("aria-controls"); 268 var panelId = $(this).closest("li").remove().attr("aria-controls");
297 var selectedIndex = $(this).closest("li").remove().attr("id"); 269 var selectedIndex = $(this).closest("li").remove().attr("id");
298 // Pause the conversation retrieval timer. 270 // Pause the conversation retrieval timer.
299 clearTimeout(getConversationsTimeout); 271 clearTimeout(getConversationsTimeout);
300 $.ajax({ 272 $.ajax({
301 type: 'post', 273 type: 'post',
302 url: "deleteConversation.php", 274 url: "deleteConversation.php",
303 data: { 275 data: {
304 firstname: $("#firstname-" + selectedIndex).val(), 276 firstname: $("#firstname-" + selectedIndex).val(),
305 lastname: $("#lastname-" + selectedIndex).val() 277 lastname: $("#lastname-" + selectedIndex).val()
306 } 278 }
307 }).done(function(data) { 279 }).done(function(data) {
308 $("#" + panelId).remove(); 280 $("#" + panelId).remove();
309 tabs.tabs("refresh"); 281 tabs.tabs("refresh");
310 // Resume the conversation retrieval timer. 282 // Resume the conversation retrieval timer.
311 getConversationsTimeout = setTimeout( 283 getConversationsTimeout = setTimeout(
312 getConversations, 284 getConversations,
313 1000 285 1000
314 ); 286 );
315 }); 287 });
316 }); 288 });
317   289  
318 // Unbind the message retrieval interval from all other tabs except the active tab. 290 // Unbind the message retrieval interval from all other tabs except the active tab.
319 tabs.on('tabsactivate', function(event, ui) { 291 tabs.on('tabsactivate', function(event, ui) {
320 var selectedIndex = ui.newTab.closest("li").attr("id"); 292 var selectedIndex = ui.newTab.closest("li").attr("id");
321 $.each(messageIntervals, function(index, value) { 293 $.each(messageIntervals, function(index, value) {
322 if (index != selectedIndex) { 294 if (index != selectedIndex) {
323 clearInterval(value); 295 clearInterval(value);
324 } 296 }
325 }); 297 });
326   298  
327 messageIntervals[selectedIndex] = setTimeout( 299 messageIntervals[selectedIndex] = setTimeout(
328 loadInstantMessage, 300 loadInstantMessage,
329 1000, 301 1000,
330 selectedIndex 302 selectedIndex
331 ); 303 );
332 }); 304 });
333   305  
334 // Start a timer to load tabs of existing conversations. 306 // Start a timer to load tabs of existing conversations.
335 getConversationsTimeout = setTimeout( 307 getConversationsTimeout = setTimeout(
336 getConversations, 308 getConversations,
337 1000 309 1000
338 ); 310 );
339   311  
340 }); 312 });
341 </script> 313 </script>
342 </body> 314 </body>
343   315  
344 </html> 316 </html>
345   317  
346
Generated by GNU Enscript 1.6.5.90.
318
Generated by GNU Enscript 1.6.5.90.
347   319  
348   320  
349   321