corrade-http-templates – Blame information for rev 62

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