1/** 2 * Wise Chat Engines namespace. 3 * 4 * @author Kainex <[email protected]> 5 * @see https://kaine.pl/projects/wp-plugins/wise-chat-pro 6 */ 7 8var wisechat = wisechat || {}; 9wisechat.engines = {}; 10 11/** 12 * AjaxEngine class. 13 * 14 * @param {Object} options Plugin's global options 15 * @constructor 16 */ 17wisechat.engines.AjaxEngine = function(options) { 18 var MESSAGES_REFRESH_TIMEOUT = options.messagesRefreshTime; 19 var messagesEndpoint = options.apiMessagesEndpointBase + '?action=wise_chat_messages_endpoint'; 20 var messageEndpoint = options.apiWPEndpointBase + '?action=wise_chat_message_endpoint'; 21 var messageGetEndpoint = options.apiEndpointBase + '?action=wise_chat_get_message_endpoint'; 22 var userCommandEndpoint = options.apiWPEndpointBase + '?action=wise_chat_user_command_endpoint'; 23 var idsCache = {}; 24 var lastId = options.lastId; 25 var isInitialized = false; 26 var currentRequest = null; 27 var currentPMRequest = null; 28 var messagesCallback = function() { }; 29 var messagesErrorCallback = function() { }; 30 var debugLoggerCallback = function() { }; 31 32 /** 33 * Starts the engine. 34 */ 35 function initialize() { 36 if (isInitialized == true) { 37 return; 38 } 39 isInitialized = true; 40 setInterval(checkNewMessages, MESSAGES_REFRESH_TIMEOUT); 41 } 42 43 function debug(message) { 44 debugLoggerCallback('[wisechat.engines.AjaxEngine] ' + message); 45 } 46 47 /** 48 * Makes AJAX request for checking new messages. 49 * It does not make new request if the previous did not complete. 50 */ 51 function checkNewMessages() { 52 if (currentRequest !== null && currentRequest.readyState > 0 && currentRequest.readyState < 4) { 53 return; 54 } 55 56 var data = { 57 channelId: options.channelId, 58 lastId: lastId, 59 checksum: options.checksum 60 }; 61 if (options.isMultisite === true) { 62 data['blogId'] = options.blogId; 63 } 64 65 currentRequest = jQuery.ajax({ 66 type: "GET", 67 url: messagesEndpoint, 68 data: data 69 }) 70 .done(onNewMessagesArrived) 71 .fail(onMessageArrivalError); 72 } 73 74 /** 75 * Loads just private messages. 76 */ 77 function loadPrivateMessages() { 78 if (currentPMRequest !== null && currentPMRequest.readyState > 0 && currentPMRequest.readyState < 4) { 79 return; 80 } 81 82 var data = { 83 channelId: options.channelId, 84 lastId: 0, 85 checksum: options.checksum, 86 privateMessages: 1 87 }; 88 if (options.isMultisite === true) { 89 data['blogId'] = options.blogId; 90 } 91 92 currentPMRequest = jQuery.ajax({ 93 type: "GET", 94 url: messagesEndpoint, 95 data: data 96 }) 97 .done(onNewMessagesArrived) 98 .fail(onMessageArrivalError); 99 } 100 101 /** 102 * Executed when AJAX request completes successfully. 103 * 104 * @param {String} result 105 */ 106 function onNewMessagesArrived(result) { 107 try { 108 var response = result; 109 if (response.result) { 110 var messagesFiltered = []; 111 for (var x = 0; x < response.result.length; x++) { 112 var msg = response.result[x]; 113 var messageId = parseInt(msg['id']); 114 if (messageId > lastId) { 115 lastId = messageId; 116 } 117 if (!idsCache[messageId]) { 118 messagesFiltered.push(msg); 119 idsCache[messageId] = true; 120 } 121 } 122 response.result = messagesFiltered; 123 messagesCallback(response); 124 } 125 } catch (e) { 126 debug('[onNewMessagesArrived] [result] ' + result); 127 debug('[onNewMessagesArrived] [exception] ' + e.toString()); 128 129 var errorDetails = ''; 130 if (jQuery.type(result) === "string") { 131 var split = result.split("\n"); 132 if (split.length > 1) { 133 errorDetails = ", " + split[1]; 134 } 135 } else { 136 errorDetails = result; 137 } 138 messagesErrorCallback('Server error: ' + e.toString() + errorDetails); 139 } 140 } 141 142 /** 143 * Executed when AJAX request completes with an error. 144 * 145 * @param {Object} jqXHR 146 * @param {String} textStatus 147 * @param {Object} errorThrown 148 */ 149 function onMessageArrivalError(jqXHR, textStatus, errorThrown) { 150 // ignore network problems: 151 if (typeof(jqXHR.status) != 'undefined' && jqXHR.status == 0) { 152 return; 153 } 154 155 try { 156 var response = jQuery.parseJSON(jqXHR.responseText); 157 if (response.error) { 158 messagesErrorCallback(response.error); 159 } 160 } catch (e) { 161 debug('[onMessageArrivalError] [responseText] ' + jqXHR.responseText); 162 debug('[onMessageArrivalError] [errorThrown] ' + errorThrown); 163 messagesErrorCallback('Server error: ' + errorThrown); 164 } 165 } 166
167 /** 168 * Sends a message using AJAX call. All the listeners must be specified. 169 * 170 * @param {Object} message 171 * @param {Function} successListener 172 * @param {Function} progressListener 173 * @param {Function} errorListener 174 */ 175 function sendMessage(message, successListener, progressListener, errorListener) { 176 if (!jQuery.isFunction(successListener) || !jQuery.isFunction(progressListener) || !jQuery.isFunction(errorListener)) { 177 throw new Error('Missing listeners'); 178 } 179 180 progressListener(0); 181 182 var data = {}; 183 if (jQuery.isPlainObject(message.customParameters)) { 184 data = message.customParameters; 185 } 186 data['attachments'] = message.attachments; 187 data['channelId'] = message.channelId; 188 data['message'] = message.content; 189 data['checksum'] = message.checksum; 190 jQuery.ajax({ 191 type: "POST", 192 url: messageEndpoint, 193 data: data, 194 progressUpload: function(evt) { 195 if (evt.lengthComputable) { 196 var percent = parseInt(evt.loaded / evt.total * 100); 197 if (percent > 100) { 198 percent = 100; 199 } 200 201 progressListener(percent); 202 } 203 } 204 }) 205 .done(function(result) { 206 try { 207 var response = result; 208 if (response.error) { 209 errorListener(response.error); 210 } else { 211 successListener(response); 212 if (options.allowToReceiveMessages) { 213 checkNewMessages(); 214 } 215 } 216 } catch (e) { 217 debug('[onMessageSent] [result] ' + result); 218 debug('[onMessageSent] [exception] ' + e.toString()); 219 errorListener('Unknown error: ' + e.toString()); 220 } 221 }) 222 .fail(function(jqXHR, textStatus, errorThrown) { 223 if (typeof(jqXHR.status) != 'undefined' && jqXHR.status == 0) { 224 errorListener('No network connection'); 225 return; 226 } 227 228 try { 229 var response = jQuery.parseJSON(jqXHR.responseText); 230 if (response.error) { 231 errorListener(response.error); 232 } else { 233 errorListener('Unknown server error occurred: ' + errorThrown); 234 } 235 } catch (e) { 236 debug('[onMessageSentError] [responseText] ' + jqXHR.responseText); 237 debug('[onMessageSentError] [errorThrown] ' + errorThrown); 238 debug('[onMessageSentError] [exception] ' + e.toString()); 239 errorListener('Server error: ' + errorThrown); 240 } 241 }); 242 } 243 244 /** 245 * Gets a message using AJAX call. All the listeners must be specified. 246 * 247 * @param {Object} message 248 * @param {Function} successListener 249 * @param {Function} errorListener 250 */ 251 function getMessage(message, successListener, errorListener) { 252 if (!jQuery.isFunction(successListener) || !jQuery.isFunction(errorListener)) { 253 throw new Error('Missing listeners'); 254 } 255 256 jQuery.ajax({ 257 type: "GET", 258 url: messageGetEndpoint, 259 data: { 260 channelId: message.channelId, 261 messageId: message.messageId, 262 checksum: message.checksum 263 } 264 }) 265 .done(function(result) { 266 try { 267 var response = result; 268 if (response.error) { 269 errorListener(response.error); 270 } else { 271 successListener(response); 272 } 273 } catch (e) { 274 debug('[onMessageGet] [result] ' + result); 275 debug('[onMessageGet] [exception] ' + e.toString()); 276 errorListener('Unknown error: ' + e.toString()); 277 } 278 }) 279 .fail(function(jqXHR, textStatus, errorThrown) { 280 if (typeof(jqXHR.status) != 'undefined' && jqXHR.status == 0) { 281 errorListener('No network connection'); 282 return; 283 } 284 285 try { 286 var response = jQuery.parseJSON(jqXHR.responseText); 287 if (response.error) { 288 errorListener(response.error); 289 } else { 290 errorListener('Unknown server error occurred: ' + errorThrown); 291 } 292 } catch (e) { 293 debug('[onMessageGet] [responseText] ' + jqXHR.responseText); 294 debug('[onMessageGet] [errorThrown] ' + errorThrown); 295 debug('[onMessageGet] [exception] ' + e.toString()); 296 errorListener('Server error: ' + errorThrown); 297 } 298 }); 299 } 300 301 /** 302 * Sends user command. 303 * 304 * @param {String} command 305 * @param {Object} parameters 306 * @param {Function} successListener 307 * @param {Function} errorListener 308 */ 309 function sendUserCommand(command, parameters, successListener, errorListener) { 310 if (!jQuery.isFunction(successListener) || !jQuery.isFunction(errorListener)) { 311 throw new Error('Missing listeners'); 312 } 313 314 parameters['command'] = command; 315 parameters['channelId'] = options.channelId; 316 parameters['checksum'] = options.checksum; 317 318 jQuery.ajax({ 319 type: "POST", 320 url: userCommandEndpoint, 321 data: parameters 322 }) 323 .done(function(result) { 324 try { 325 var response = result; 326 if (response && response.error) { 327 errorListener(response.error); 328 } else { 329 successListener(response); 330 } 331 } catch (e) { 332 debug('[sendUserCommand] [result] ' + result); 333 debug('[sendUserCommand] [exception] ' + e.toString()); 334 errorListener('Unknown error: ' + e.toString()); 335 } 336 }) 337 .fail(function(jqXHR, textStatus, errorThrown) { 338 if (typeof(jqXHR.status) != 'undefined' && jqXHR.status == 0) { 339 errorListener('No network connection'); 340 return; 341 } 342 343 try { 344 var response = jQuery.parseJSON(jqXHR.responseText); 345 if (response && typeof response.error !== 'undefined') { 346 errorListener(response.error); 347 } else { 348 errorListener('Unknown server error occurred: ' + errorThrown); 349 } 350 } catch (e) { 351 debug('[sendUserCommand] [responseText] ' + jqXHR.responseText); 352 debug('[sendUserCommand] [errorThrown] ' + errorThrown); 353 debug('[sendUserCommand] [exception] ' + e.toString()); 354 errorListener('Server error: ' + errorThrown); 355 } 356 }); 357 } 358 359 function setMessagesCallback(callback) { 360 messagesCallback = callback; 361 } 362 363 function setMessagesErrorCallback(callback) { 364 messagesErrorCallback = callback; 365 } 366 367 function setDebugLoggerCallback(callback) { 368 debugLoggerCallback = callback; 369 } 370 371 // API: 372 this.initialize = initialize; 373 this.loadPrivateMessages = loadPrivateMessages; 374 this.sendMessage = sendMessage; 375 this.getMessage = getMessage; 376 this.setMessagesCallback = setMessagesCallback; 377 this.setMessagesErrorCallback = setMessagesErrorCallback; 378 this.setDebugLoggerCallback = setDebugLoggerCallback; 379 this.sendUserCommand = sendUserCommand; 380};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.