Advertisement
Guest User

Untitled

a guest
Jun 11th, 2017
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 38.83 KB | None | 0 0
  1. // ==UserScript==
  2. // @name RPH Tools
  3. // @namespace https://openuserjs.org/scripts/shuffyiosys/RPH_Tools
  4. // @version 3.1.1
  5. // @description Adds extended settings to RPH
  6. // @match http://chat.rphaven.com
  7. // @copyright (c)2014 shuffyiosys@github
  8. // @grant none
  9. // @license MIT license (https://en.wikipedia.org/wiki/MIT_License)
  10. // ==/UserScript==
  11. /*jshint multistr: true */
  12. /*jshint bitwise: false*/
  13. /*global $:false */
  14.  
  15. /* Template for Modules
  16. var = (function(){
  17. html = '';
  18. return {
  19. init : function(){
  20. },
  21.  
  22. getHtml : function(){
  23. return html;
  24. },
  25.  
  26. toString : function(){
  27. return ' Module';
  28. },
  29. };
  30. }());
  31. */
  32.  
  33. var VERSION_STRING = 'RPH Tools 3.1.1';
  34.  
  35. var settingsDialog = {};
  36.  
  37. var GetInput = function(settingId) {
  38. return $('#' + settingId).val();
  39. };
  40.  
  41. var GetCheckBox = function(settingId) {
  42. return $('#' + settingId).is(':checked');
  43. };
  44.  
  45. var DialogToggle = function(event) {
  46. var dialog = event.data.dialog;
  47. if (dialog.state === false) {
  48. if (event.data.onOpen !== undefined) {
  49. event.data.onOpen();
  50. }
  51. dialog.form.show();
  52. dialog.state = true;
  53. } else {
  54. if (event.data.onClose !== undefined) {
  55. event.data.onClose();
  56. }
  57. dialog.form.hide();
  58. dialog.state = false;
  59. }
  60. };
  61.  
  62. var CreateDialog = function(element, form) {
  63. return {
  64. button: $(element),
  65. form: $(form),
  66. state: false
  67. };
  68. };
  69.  
  70. var MarkProblem = function(element, mark) {
  71. if (mark === true) {
  72. $("#" + element).css('background', '#FF7F7F');
  73. } else {
  74. $("#" + element).css('background', '#FFF');
  75. }
  76. };
  77.  
  78. var ValidateSetting = function(settingId, setting) {
  79. var validInput = false;
  80. var input = $('#' + settingId).val();
  81.  
  82. switch (setting) {
  83. case "url":
  84. validInput = ValidateUrl(input);
  85. break;
  86.  
  87. case "color":
  88. validInput = ValidateColor(input);
  89. break;
  90. }
  91. MarkProblem(settingId, !validInput);
  92. return validInput;
  93. };
  94.  
  95. var ValidateColor = function(color) {
  96. var pattern = new RegExp(/(^#[0-9A-Fa-f]{6}$)|(^#[0-9A-Fa-f]{3}$)/i);
  97. return pattern.test(color);
  98. };
  99.  
  100. var ValidateUrl = function(url) {
  101. var match = false;
  102. var regexp = /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/;
  103. var pingExt = url.slice((url.length - 4), (url.length));
  104.  
  105. if (url === '') {
  106. match = true;
  107. } else if (regexp.test(url) === true) {
  108. if (pingExt == ".wav" || pingExt == ".ogg" || pingExt == ".mp3") {
  109. match = true;
  110. }
  111. }
  112. return match;
  113. };
  114.  
  115. /****************************************************************************
  116. * @brief: Tests the color range of the color to ensure its valid
  117. * @param: TextColor - String representation of the color.
  118. *
  119. * @return: True if the color is within range, false otherwise.
  120. ****************************************************************************/
  121. var ValidateColorRange = function(TextColor) {
  122. var rawHex = TextColor.substring(1, TextColor.length);
  123. var red = 255;
  124. var green = 255;
  125. var blue = 255;
  126.  
  127. /* If the color text is 3 characters, limit it to #DDD */
  128. if (rawHex.length == 3) {
  129. red = parseInt(rawHex.substring(0, 1), 16);
  130. green = parseInt(rawHex.substring(1, 2), 16);
  131. blue = parseInt(rawHex.substring(2, 3), 16);
  132.  
  133. if ((red <= 13) && (green <= 13) && (blue <= 13)) {
  134. return true;
  135. }
  136. }
  137. /* If the color text is 6 characters, limit it to #D2D2D2 */
  138. else if (rawHex.length == 6) {
  139. red = parseInt(rawHex.substring(0, 2), 16);
  140. green = parseInt(rawHex.substring(2, 4), 16);
  141. blue = parseInt(rawHex.substring(4, 6), 16);
  142. if ((red <= 210) && (green <= 210) && (blue <= 210)) {
  143. return true;
  144. }
  145. }
  146.  
  147. console.log('RPH Tools[ValidateColorRange]: Color check failed', rawHex, red, green, blue);
  148. return false;
  149. };
  150.  
  151. /****************************************************************************
  152. * @brief Adds usernames to droplists.
  153. * @param user_id - ID of username
  154. ****************************************************************************/
  155. var AddUserToDroplist = function(user_id, droplist) {
  156. getUserById(user_id, function(User) {
  157. $('#' + droplist).append('<option value="' + user_id + '">' +
  158. User.props.name + '</option>');
  159. });
  160. };
  161.  
  162. /****************************************************************************
  163. * @brief Clears droplists.
  164. ****************************************************************************/
  165. var ClearUsersDropLists = function(droplist) {
  166. $('#' + droplist).empty();
  167. };
  168.  
  169. /****************************************************************************
  170. * @brief In an array of object, return the first instance where a key
  171. * matches a value.
  172. *
  173. * @param objArray - Array of objects
  174. * @param key - Key to look for
  175. * @param value - Value of the key to match
  176. * @return Index of the first instance where the key matches the value, -1
  177. * otherwise.
  178. ****************************************************************************/
  179. var ArrayObjectIndexOf = function(objArray, key, value) {
  180. for (var i = 0; i < objArray.length; i++) {
  181. if (objArray[i][key] === value) {
  182. return i;
  183. }
  184. }
  185. return -1;
  186. };
  187.  
  188. /****************************************************************************
  189. * @brief: Checks if a search term is in an <a href=...> tag.
  190. * @param: searchTerm - String to look for
  191. * @param: msg - msg being searched.
  192. *
  193. * @return: True or false if there's a match.
  194. ****************************************************************************/
  195. var IsInLink = function(searchTerm, msg) {
  196. var regexp = new RegExp('href=".*?' + searchTerm + '.*?"', '');
  197. return regexp.test(msg);
  198. };
  199.  
  200. /****************************************************************************
  201. * @brief Generates a hash value for a string
  202. *
  203. * @note This was modified from https://stackoverflow.com/questions/7616461/generate-a-hash-from-string-in-javascript-jquery
  204. ****************************************************************************/
  205. String.prototype.hashCode = function() {
  206. var hash = 0,
  207. i, chr, len;
  208. if (this.length === 0) return hash;
  209. for (i = 0, len = this.length; i < len; i++) {
  210. chr = this.charCodeAt(i);
  211. hash = ((hash << 31) - hash) + chr;
  212. hash |= 0; // Convert to 32bit integer
  213. }
  214. return hash;
  215. };
  216.  
  217. /****************************************************************************
  218. * @brief: Checks if the current account is a mod of the room.
  219. *
  220. * @param: roomName: Name of the room.
  221. ****************************************************************************/
  222. var IsModOfRoom = function(room){
  223. for(var idx = 0; idx < account.users.length; idx++){
  224. if (room.props.mods.indexOf(account.users[idx]) > -1 ||
  225. room.props.owners.indexOf(account.users[idx]) > -1 ){
  226. return true;
  227. }
  228. }
  229. return false;
  230. };
  231.  
  232. /****************************************************************************
  233. * @brief: Module for handling the chat functions of the script.
  234. ****************************************************************************/
  235. var ChatModule = (function() {
  236. var pingSettings = {
  237. 'triggers': [],
  238. 'audioUrl': 'http://chat.rphaven.com/sounds/boop.mp3',
  239. 'color': '#000',
  240. 'highlight': '#FFA',
  241. 'bold': false,
  242. 'italics': false,
  243. 'exact': false,
  244. 'case': false,
  245. };
  246.  
  247. var chatSettings = {
  248. 'showNames': true,
  249. 'noIcons': false,
  250. 'strictUrl': false,
  251. 'canCancel': false,
  252. 'autoJoin': false,
  253. 'session': false,
  254. 'roomSession': [],
  255. 'favRooms': [],
  256. };
  257.  
  258. var localStorageName = "rpht_ChatModule";
  259.  
  260. var pingSound = null;
  261.  
  262. var autoJoinTimer = null;
  263.  
  264. var updateSessionTimer = null;
  265.  
  266. var waitForDialog = true;
  267.  
  268. var html =
  269. '<h3 class="rpht_headers" id="chatSettingsHeader">Chat room</h3>' +
  270. '<div id="chatSettingsForm" style="display:none;">' +
  271. '<p style="border-bottom: 2px solid #EEE;">' +
  272. '<span style="background: #333; position: relative; top: 0.7em;"><strong>User text color</strong>&nbsp;</span>' +
  273. '</p>' +
  274. '<div class="rpht-block"><label>Username:</label><select style="width: 300px;" id="userColorDroplist"></select></div>' +
  275. '<div class="rpht-block"><label>Text color:</label><input style="width: 300px;" type="text" id="userNameTextColor" name="userNameTextColor" value="#111"></div>' +
  276. '<div class="rpht-block"><button type="button" id="userNameTextColorButton">Set color</button></div>' +
  277. '<p style="border-bottom: 2px solid #EEE;">' +
  278. '<span style="background: #333; position: relative; top: 0.7em;"><strong>Pings</strong>&nbsp;</span>' +
  279. '</p><br />' +
  280. '<p>Names to be pinged (comma separated)</p>' +
  281. '<textarea id="pingNames" class="rpht_textarea" name="pingNames"> </textarea>' +
  282. '<br /><br />' +
  283. '<div class="rpht-block"><label>Ping URL: </label><input style="width: 370px;" type="text" id="pingURL" name="pingURL"></div>' +
  284. '<div class="rpht-block"><label>Text Color: </label><input style="width: 370px;" type="text" id="pingTextColor" name="pingTextColor" value="#000"></div>' +
  285. '<div class="rpht-block"><label>Highlight: </label><input style="width: 370px;" type="text" id="pingHighlightColor" name="pingHighlightColor" value="#FFA"></div>' +
  286. '<br>' +
  287. '<p>Matching options</p> <br/>' +
  288. '<input style="width: 40px;" type="checkbox" id="pingBoldEnable" name="pingBoldEnable"><strong>Bold</strong>' +
  289. '<input style="width: 40px;" type="checkbox" id="pingItalicsEnable" name="pingItalicsEnable"><em>Italics</em>' +
  290. '<input style="width: 40px;" type="checkbox" id="pingExactMatch" name="pingExactMatch">Exact match' +
  291. '<input style="width: 40px;" type="checkbox" id="pingCaseSense" name="pingCaseSense">Case sensitive' +
  292. '<br /><br />' +
  293. '<p style="border-bottom: 2px solid #EEE;">' +
  294. '<span style="background: #333; position: relative; top: 0.7em;"><strong>Auto Joining</strong>&nbsp; </span>' +
  295. '</p>' +
  296. '<div class="rpht-block"><label>Can Cancel: </label><input type="checkbox" id="canCancelJoining" name="canCancelJoining" checked></div>' +
  297. '<div class="rpht-block"><label>Room Sessioning: </label><input type="checkbox" id="roomSessioning" name="roomSessioning"></div>' +
  298. '<div class="rpht-block"><label>Join favorites: </label><input type="checkbox" id="favEnable" name="favEnable"></div>' +
  299. '<div class="rpht-block"><label>Username: </label><select style="width: 300px;" id="favUserList"></select></div>' +
  300. '<div class="rpht-block"><label>Room: </label><input style="width: 370px;" type="text" id="favRoom" name="favRoom"></div>' +
  301. '<div class="rpht-block"><label>Password: </label><input style="width: 370px;" type="text" id="favRoomPw" name="favRoomPw"></div>' +
  302. '<div class="rpht-block"><button type="button" id="favAdd">Add</button></div>' +
  303. '<p>Favorite rooms</p>' +
  304. '<select style="width: 403px;" id="favRoomsList" size="5"></select><br><br>' +
  305. '<div class="rpht-block"><button type="button" id="favRemove">Remove</button></div>' +
  306. '<br>' +
  307. '<p style="border-bottom: 2px solid #EEE;">' +
  308. '<span style="background: #333; position: relative; top: 0.7em;"><strong>Other Settings</strong>&nbsp; </span>' +
  309. '</p><br />' +
  310. '<div class="rpht-block"><label>Chat history: </label><input style="width: 300px;" type="number" id="chatHistory" name="chatHistory" max="65535" min="10" value="300"><br /><br /></div>' +
  311. '<div class="rpht-block"><label>No image icons in chat</label><input style="margin-right: 10px;" type="checkbox" id="imgIconDisable" name="imgIconDisable"></div>' +
  312. '<div class="rpht-block"><label>Show username in tabs & textbox (requires rejoin)</label><input style="margin-right: 10px;" type="checkbox" id="showUsername" name="showUsername"></div>' +
  313. '<div class="rpht-block"><label>Strict URL parser</label><input style="margin-right: 10px;" type="checkbox" id="strictUrl" name="strictUrl"></div>' +
  314. '</div>' +
  315. '<br />';
  316.  
  317. /**************************************************************************
  318. * @brief: When user joins a room, do the following:
  319. * - Set up the .onMessage function for pinging
  320. * - Add the user's name to the chat tab and textarea
  321. * - Create a room-pair name for the Modding section
  322. * @param: room - Room that the user has joined
  323. **************************************************************************/
  324. var roomSetup = function(room) {
  325. var thisRoom = getRoom(room.room);
  326. var userId = GetIdFromChatTab(thisRoom);
  327. var moddingModule = RphToolsModule.GetModule('Modding Module');
  328.  
  329. thisRoom.onMessage = function(data) {
  330. var thisRoom = this;
  331. if (account.ignores.indexOf(data.userid) !== -1) {
  332. return;
  333. }
  334. postMessage(thisRoom, data);
  335. };
  336.  
  337. if (chatSettings.showNames) {
  338. AddNameToUI(thisRoom, userId);
  339. }
  340.  
  341. if (moddingModule !== null) {
  342. getUserById(room.userid, function(User) {
  343. var classes = GetClasses(User, thisRoom);
  344. moddingModule.AddModFeatures(thisRoom, userId, classes);
  345. });
  346. }
  347.  
  348. ResizeChatTabs();
  349. if (jQuery._data(window, "events").resize === undefined) {
  350. $(window).resize(ResizeChatTabs);
  351. }
  352.  
  353. if (chatSettings.session === true) {
  354. if (ArrayObjectIndexOf(chatSettings.roomSession, 'roomname', room.room) === -1 ||
  355. ArrayObjectIndexOf(chatSettings.roomSession, 'user', room.userid) === -1) {
  356. var tempData = {
  357. 'roomname': room.room,
  358. 'user': room.userid
  359. };
  360. chatSettings.roomSession.push(tempData);
  361. }
  362. }
  363. };
  364.  
  365. /****************************************************************************
  366. * @brief: Takes a message received in the chat and modifies it if it has
  367. * a match for pinging
  368. * @param: thisRoom - The room that the message is for.
  369. * @param: data - The message for the room
  370. ****************************************************************************/
  371. var postMessage = function(thisRoom, data) {
  372. getUserById(data.userid, function(User) {
  373. var timestamp = makeTimestamp(data.time);
  374. var msg = parseMsg_rpht(data.msg);
  375. var classes = '';
  376. var $el = '';
  377. var msgHtml = '';
  378.  
  379. if (User.blocked) {
  380. return;
  381. }
  382.  
  383. classes = GetClasses(User, thisRoom);
  384.  
  385. /* Check if this is a valid RNG */
  386. if (msg[msg.length - 1] === '\u200b') {
  387. msg += '&nbsp;<span style="background:#4A4; color: #000;">☑</span>';
  388. }
  389.  
  390. /* Add pinging higlights */
  391. try {
  392. var testRegex = null;
  393. testRegex = MatchPing(msg, pingSettings.triggers, pingSettings.case,
  394. pingSettings.exact);
  395. if (testRegex !== null) {
  396. msg = HighlightPing(msg, testRegex, pingSettings.color,
  397. pingSettings.highlight, pingSettings.bold,
  398. pingSettings.italics);
  399. HighlightRoom(thisRoom, pingSettings.color, pingSettings.highlight);
  400. if (pingSound !== null) {
  401. pingSound.play();
  402. }
  403. }
  404.  
  405. if (ModdingModule !== null && IsModOfRoom(thisRoom) === true){
  406. var modSettings = ModdingModule.GetSettings();
  407. testRegex = MatchPing(msg, modSettings.alertWords, false, true);
  408. if (testRegex !== null) {
  409. msg = HighlightPing(msg, testRegex, "#EEE", "#E00", true, false);
  410. HighlightRoom(thisRoom, "#EEE", "#E00");
  411. if (pingSound !== null) {
  412. ModdingModule.PlayAlert();
  413. }
  414. ModdingModule.AutoKick(thisRoom, data.userid, msg);
  415. }
  416. }
  417. } catch (err) {
  418. console.log('RPH Tools[postMessage]: I tried pinging D:', err);
  419. msg = parseMsg_rpht(data.msg);
  420. }
  421.  
  422. if (msg.charAt(0) === '/' && msg.slice(1, 3) === 'me') {
  423. classes += 'action ';
  424. msg = msg.slice(3);
  425. msgHtml = '<span class="first">[' + timestamp +
  426. ']</span>\n<span style="color:#' + User.props.color +
  427. '"><a class="name" title="[' + timestamp +
  428. ']" style="color:#' + User.props.color +
  429. '">' + User.props.name + '</a>' + msg + '</span>';
  430. } else {
  431. msgHtml = '<span class="first">[' + timestamp + ']<a class="name" title="[' +
  432. timestamp + ']" style="color:#' + User.props.color + '">' +
  433. User.props.name +
  434. '<span class="colon">:</span></a></span>\n<span style="color:#' +
  435. User.props.color + '">' + msg + '</span>';
  436. }
  437.  
  438. if (chatSettings.noIcons) {
  439. $el = AppendMessageTextOnly(msgHtml, thisRoom).addClass(classes);
  440. } else {
  441. $el = thisRoom.appendMessage(msgHtml).addClass(classes);
  442. }
  443. $el.find('br:gt(7)').remove();
  444. });
  445. };
  446.  
  447. /****************************************************************************
  448. * @brief: Gets the user name's classes that are applicable to it
  449. * @param: User - User of the message
  450. * @param: thisRoom - Room that the message is being sent to
  451. ****************************************************************************/
  452. var GetClasses = function(User, thisRoom) {
  453. var classes = '';
  454. if (User.friendOf) {
  455. classes += 'friend ';
  456. }
  457. if (isOwnUser(User)) {
  458. classes += 'self ';
  459. }
  460. if (isOwnerOf(thisRoom, User)) {
  461. classes += 'owner ';
  462. } else if (isModOf(thisRoom, User)) {
  463. classes += 'mod ';
  464. }
  465. if (isInGroup(thisRoom, User)) {
  466. classes += 'group-member ';
  467. }
  468.  
  469. return classes;
  470. };
  471.  
  472. /****************************************************************************
  473. * @brief: Checks if the message has any ping terms
  474. * @param: msg - The message for the chat as a string.
  475. *
  476. * @return: Returns the match or null
  477. ****************************************************************************/
  478. var MatchPing = function(msg, triggers, caseSensitive, exactMatch) {
  479. var testRegex = null;
  480. var pingNames = triggers.split(',');
  481. var regexParam = (caseSensitive ? "m" : 'im');
  482. if (triggers.length === 0) {
  483. return testRegex;
  484. }
  485.  
  486. for (i = 0; i < pingNames.length; i++) {
  487. if (pingNames[i] !== "") {
  488. var regexPattern = pingNames[i].trim();
  489. if (exactMatch === true) {
  490. regexPattern = "\\b" + pingNames[i].trim() + "\\b";
  491. }
  492.  
  493. /* Check if search term is not in a link. */
  494. if (IsInLink(pingNames[i], msg) === false) {
  495. testRegex = new RegExp(regexPattern, regexParam);
  496. if (msg.match(testRegex)) {
  497. return testRegex;
  498. }
  499. }
  500. }
  501. }
  502. return null;
  503. };
  504.  
  505. /****************************************************************************
  506. * @brief: Adds highlights to the ping term
  507. * @param: msg - Message to be sent to the chat.
  508. * @param: testRegex - Regular expression to use to match the term.
  509. *
  510. * @param: Modified msg.
  511. ****************************************************************************/
  512. var HighlightPing = function(msg, testRegex, color, highlight, bold, italicize) {
  513. var boldEnabled = "";
  514. var italicsEnabled = "";
  515.  
  516. if (bold === true) {
  517. boldEnabled = "font-weight: bold; ";
  518. }
  519.  
  520. if (italicize === true) {
  521. italicsEnabled = "font-style:italic; ";
  522. }
  523. msg = msg.replace(testRegex, '<span style="color: ' + color +
  524. '; background: ' + highlight + '; ' + boldEnabled +
  525. italicsEnabled + '">' + msg.match(testRegex) + '</span>');
  526.  
  527. return msg;
  528. };
  529.  
  530. /****************************************************************************
  531. * @brief: Adds a highlight to the room's tab
  532. * @param: thisRoom - Room where the ping happened.
  533. ****************************************************************************/
  534. var HighlightRoom = function(thisRoom, color, highlight) {
  535. //Don't highlight chat tab if the chat is marked as active.
  536. var testRegex = new RegExp('active', 'im');
  537. var className = thisRoom.$tabs[0][0].className;
  538.  
  539. if (className.search(testRegex) == -1) {
  540. thisRoom.$tabs[0].css('background-color', highlight);
  541. thisRoom.$tabs[0].css('color', color);
  542.  
  543. thisRoom.$tabs[0].click(function() {
  544. thisRoom.$tabs[0].css('background-color', '#333');
  545. thisRoom.$tabs[0].css('color', '#6F9FB9');
  546.  
  547. thisRoom.$tabs[0].hover(function() {
  548. thisRoom.$tabs[0].css('background-color', '#6F9FB9');
  549. thisRoom.$tabs[0].css('color', '#333');
  550. }, function() {
  551. thisRoom.$tabs[0].css('background-color', '#333');
  552. thisRoom.$tabs[0].css('color', '#6F9FB9');
  553. });
  554. });
  555. }
  556. };
  557.  
  558. /****************************************************************************
  559. * @brief: Adds user name to chat tab and chat textarea
  560. * @param: thisRoom - Room that was entered
  561. * @param: userId - ID of the user that entered
  562. ****************************************************************************/
  563. var AddNameToUI = function(thisRoom, userId) {
  564. getUserById(userId, function(User) {
  565. var tabsLen = thisRoom.$tabs.length;
  566. var idRoomName = thisRoom.$tabs[tabsLen - 1][0].className.split(' ')[2];
  567. var newTabHtml = '<span>' + thisRoom.props.name + '</span><p style="font-size: x-small; position: absolute; top: 12px;">' + User.props.name + '</p>';
  568. thisRoom.$tabs[tabsLen - 1].html(newTabHtml);
  569. $('<a class="close ui-corner-all">x</a>').on('click', function(ev) {
  570. ev.stopPropagation();
  571. chatSocket.emit('leave', {
  572. userid: User.props.id,
  573. name: thisRoom.props.name
  574. });
  575. }).appendTo(thisRoom.$tabs[tabsLen - 1]);
  576. $('textarea.' + idRoomName).prop('placeholder', 'Post as ' + User.props.name);
  577. $('textarea.' + idRoomName).css('color', "#" + User.props.color);
  578. });
  579. };
  580.  
  581. /****************************************************************************
  582. * @brief: Gets the user's ID from the chat tab (it's in the class)
  583. * @param: thisRoom - Room to get the ID from
  584. ****************************************************************************/
  585. var GetIdFromChatTab = function(thisRoom) {
  586. var tabsLen = thisRoom.$tabs.length;
  587. var className = thisRoom.$tabs[tabsLen - 1][0].className;
  588. var charID = className.match(new RegExp(' [0-9]+', ''))[0];
  589. charID = charID.substring(1, charID.length);
  590. return parseInt(charID);
  591. };
  592.  
  593. /****************************************************************************
  594. * @brief Appends message to a room without adding an image icon
  595. * @param html - HTML to add to the room.
  596. * @param thisRoom - Object to the room receiving the message.
  597. *
  598. * @note This was modified from RPH's original code, which is not covered
  599. * by this license.
  600. ****************************************************************************/
  601. var AppendMessageTextOnly = function(html, thisRoom) {
  602. var $el = $('<div>\n' + html + '\n</div>').appendTo(thisRoom.$el);
  603. var extra = 5; //add more if near the bottom
  604. if (thisRoom.$el[0].scrollHeight - thisRoom.$el.scrollTop() < 50) {
  605. extra = 60;
  606. }
  607. thisRoom.$el.animate({
  608. scrollTop: '+=' + ($el.outerHeight() + extra)
  609. }, 180);
  610.  
  611. if (thisRoom.$el.children('div').length > account.settings.maxHistory) {
  612. thisRoom.$el.children('div:not(.sys):lt(3)').remove();
  613. }
  614.  
  615. return $el;
  616. };
  617.  
  618. /****************************************************************************
  619. * @brief: Resizes chat tabs accordingly
  620. ****************************************************************************/
  621. var ResizeChatTabs = function() {
  622. $('#chat-tabs').addClass('rpht_chat_tab');
  623.  
  624. if ($('#chat-tabs')[0].clientWidth < $('#chat-tabs')[0].scrollWidth ||
  625. $('#chat-tabs')[0].clientWidth + 200 > $('#chat-bottom')[0].clientWidth) {
  626. $('#chat-top .inner').css('height', 'calc(100% - 20px)');
  627. $('#chat-bottom').css({
  628. 'margin-top': '-160px',
  629. 'height': '120px'
  630. });
  631. $('#chat-tabs').addClass('rpht_chat_tab_scroll');
  632. $('#chat-tabs').css('width', $('#chat-bottom')[0].clientWidth - 200);
  633. } else {
  634. $('#chat-top .inner').removeAttr('style');
  635. $('#chat-bottom').css({
  636. 'margin-top': '-140px'
  637. });
  638. $('#chat-tabs').removeClass('rpht_chat_tab_scroll');
  639. $('#chat-tabs').css('width', 'auto');
  640. }
  641. };
  642.  
  643. var parseMsg_rpht = function(msg) {
  644. var regex_html_loose = /((ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?|^([a-zA-Z0-9]+(\.[a-zA-Z0-9]+)+.*)$)/gi;
  645. var regex_html_strict = /https?:\/\/(www\.)?[-a-zA-Z0-9@:%_\+.~#?&//=]{2,256}\.[a-z]{2,4}\b(\/[-a-zA-Z0-9@:%_\+.~#?&//=]*)?/gi;
  646. var regex_in_use = (chatSettings.strictUrl ? regex_html_strict : regex_html_loose);
  647. msg = msg.replace(/</g, '&lt;');
  648. msg = msg.replace(/>/g, '&gt;');
  649. msg = msg.replace(/\n/g, '<br />');
  650. msg = msg.replace(/="/g, '');
  651. msg = msg.replace(/(\[b\]|\*\*)(.*?)(\[\/b\]|\*\*)/g, '<strong>$2</strong>');
  652. msg = msg.replace(/(\-\-\-)/g, '&mdash;');
  653. msg = msg.replace(/(\[s\]|\-\-)(.*?)(\[\/s\]|\-\-)/g, '<strike>$2</strike>');
  654. msg = msg.replace(/(?:\[i\]|\/\/)([^\/].*?)(?:\[\/i\]|\/\/)/g, function(str, p1, offset, s) {
  655. if (s.charAt(offset - 1) == ":") {
  656. return str;
  657. } else {
  658. return "<em>" + $('<div>' + p1 + '</div>').text() + "</em>";
  659. }
  660. });
  661.  
  662. msg = msg.replace(regex_in_use,
  663. function(url) {
  664. var full_url = url;
  665. if (!full_url.match('^https?:\/\/')) {
  666. full_url = 'http://' + full_url;
  667. }
  668. return '<a href="' + $('<div>' + full_url + '</div>').text() + '" target="_blank">' + $('<div>' + url + '</div>').text() + '</a>';
  669. });
  670.  
  671. return msg;
  672. };
  673.  
  674. var autoJoiningHandler = function() {
  675. if (roomnames.length > 0) {
  676. if (waitForDialog === true) {
  677. $('<div id="rpht-autojoin" class="inner">' +
  678. '<p>Autojoining or restoring session.</p>' +
  679. '<p>Press "Cancel" to stop autojoin or session restore.</p>' +
  680. '</div>').dialog({
  681. open: function(event, ui) {
  682. setTimeout(function() {
  683. $('#rpht-autojoin').dialog('close');
  684. }, 10 * 1000);
  685. },
  686. buttons: {
  687. Cancel: function() {
  688. clearTimeout(autoJoinTimer);
  689. $(this).dialog("close");
  690. }
  691. },
  692. }).dialog('open');
  693.  
  694. waitForDialog = false;
  695. clearTimeout(autoJoinTimer);
  696. autoJoinTimer = setTimeout(autoJoiningHandler, 10 * 1000);
  697. } else {
  698. if (chatSettings.autoJoin === true) {
  699. JoinFavoriteRooms();
  700. }
  701. if (chatSettings.session) {
  702. for (var i = 0; i < chatSettings.roomSession.length; i++) {
  703. var room = chatSettings.roomSession[i];
  704. var roomInFavs = ArrayObjectIndexOf(chatSettings.favRooms, 'room', room.roomname) > -1;
  705. var userInFavs = ArrayObjectIndexOf(chatSettings.favRooms, 'userId', room.user) > -1;
  706. var canJoin = (roomInFavs != userInFavs) || chatSettings.autoJoin;
  707.  
  708. /* Restore session if:
  709. User xor room are not in favorites
  710. Autojoin is not enabled.
  711. */
  712. if (canJoin) {
  713. chatSocket.emit('join', {
  714. name: room.roomname,
  715. userid: room.user
  716. });
  717. }
  718. }
  719. }
  720. chatSettings.roomSession = [];
  721. clearTimeout(autoJoinTimer);
  722. }
  723. }
  724. };
  725.  
  726. var JoinFavoriteRooms = function() {
  727. console.log('Joining favorite rooms');
  728. for (var i = 0; i < chatSettings.favRooms.length; i++) {
  729. var favRoom = chatSettings.favRooms[i];
  730. console.log('Joining favorite room', favRoom);
  731. chatSocket.emit('join', {
  732. name: favRoom.room,
  733. userid: favRoom.userId,
  734. pw: favRoom.roomPw
  735. });
  736. }
  737. };
  738.  
  739. var updateSession = function() {
  740. var tempSession = [];
  741. for (var i = 0; i < rph.roomsJoined.length; i++) {
  742. var roomname = rph.roomsJoined[i].roomname;
  743. if (ArrayObjectIndexOf(chatSettings.roomSession, 'roomname', roomname) !== -1) {
  744. tempSession.push(rph.roomsJoined[i]);
  745. }
  746. }
  747. chatSettings.roomSession = tempSession;
  748. SaveSettings();
  749. };
  750.  
  751. var AddFavoriteRoom = function() {
  752. var room = getRoom($('#favRoom').val());
  753.  
  754. if (room === undefined) {
  755. MarkProblem('favRoom', true);
  756. return;
  757. }
  758.  
  759. if (chatSettings.favRooms.length < 10) {
  760. var favExists = false;
  761. var hashStr = $('#favRoom').val() + $('#favUserList option:selected').html();
  762. var favRoomObj = {
  763. _id: hashStr.hashCode(),
  764. user: $('#favUserList option:selected').html(),
  765. userId: parseInt($('#favUserList option:selected').val()),
  766. room: $('#favRoom').val(),
  767. roomPw: $('#favRoomPw').val()
  768. };
  769.  
  770. MarkProblem('favRoom', false);
  771. if (ArrayObjectIndexOf(chatSettings.favRooms, "_id", favRoomObj._id) === -1) {
  772. $('#favRoomsList').append(
  773. '<option value="' + favRoomObj._id + '">' +
  774. favRoomObj.user + ": " + favRoomObj.room + '</option>'
  775. );
  776. chatSettings.favRooms.push(favRoomObj);
  777. console.log('RPH Tools[AddFavoriteRoom]: Added favorite room', favRoomObj);
  778. }
  779.  
  780. if (chatSettings.favRooms.length >= 10) {
  781. $('#favAdd').text("Favorites Full");
  782. $('#favAdd')[0].disabled = true;
  783. }
  784. }
  785. };
  786.  
  787. var RemoveFavoriteRoom = function() {
  788. var favItem = document.getElementById("favRoomsList");
  789. var favItemId = $('#favRoomsList option:selected').val();
  790. favItem.remove(favItem.selectedIndex);
  791.  
  792. for (var favs_i = 0; favs_i < chatSettings.favRooms.length; favs_i++) {
  793. if (chatSettings.favRooms[favs_i]._id == favItemId) {
  794. chatSettings.favRooms.splice(favs_i, 1);
  795. break;
  796. }
  797. }
  798.  
  799. if (chatSettings.favRooms.length < 10) {
  800. $('#favAdd').text("Add");
  801. $('#favAdd')[0].disabled = false;
  802. }
  803. };
  804.  
  805. var ChangeTextColor = function() {
  806. var text_color = $('input#userNameTextColor').val();
  807. if (ValidateColor(text_color) === false ||
  808. ValidateColorRange(text_color) === false) {
  809. MarkProblem('userNameTextColor', true);
  810. } else {
  811. var userId = $('#userColorDroplist option:selected').val();
  812.  
  813. text_color = text_color.substring(1, text_color.length);
  814. getUserById(userId, function(User) {
  815. MarkProblem('userNameTextColor', false);
  816. sendToSocket('modify', {
  817. userid: User.props.id,
  818. color: text_color
  819. });
  820. });
  821. }
  822. };
  823.  
  824. var SaveSettings = function() {
  825. localStorage.setItem(localStorageName, JSON.stringify(GetSettings()));
  826. };
  827.  
  828. var LoadSettings = function(storedSettings) {
  829. if (storedSettings !== null) {
  830. chatSettings = storedSettings.chatSettings;
  831. pingSettings = storedSettings.pingSettings;
  832. }
  833. PopulateSettings();
  834. };
  835.  
  836. var LoadOldSettings = function() {
  837. var oldSettings = JSON.parse(localStorage.getItem("chatSettings"));
  838. if (oldSettings !== null) {
  839. pingSettings.triggers = oldSettings.pings;
  840. pingSettings.audioUrl = oldSettings.ping_url;
  841. pingSettings.color = oldSettings.color;
  842. pingSettings.highlight = oldSettings.highlight;
  843. pingSettings.bold = ((oldSettings.flags & 2) > 0);
  844. pingSettings.italics = ((oldSettings.flags & 4) > 0);
  845. pingSettings.exact = ((oldSettings.flags & 8) > 0);
  846. pingSettings.case = ((oldSettings.flags & 16) > 0);
  847.  
  848. chatSettings.showNames = ((oldSettings.flags & 64) > 0);
  849. chatSettings.noIcons = ((oldSettings.flags & 128) > 0);
  850. chatSettings.session = oldSettings.session;
  851. chatSettings.strictUrl = oldSettings.strictUrl;
  852. chatSettings.canCancel = !oldSettings.alwaysJoin;
  853. chatSettings.favRooms = oldSettings.favRooms;
  854. chatSettings.autoJoin = oldSettings.autoJoin;
  855. }
  856.  
  857. oldSettings = JSON.parse(localStorage.getItem("lastSession"));
  858. if (oldSettings !== null) {
  859. chatSettings.roomSession = oldSettings;
  860. }
  861. SaveSettings();
  862. PopulateSettings();
  863. };
  864.  
  865. var DeleteSettings = function() {
  866. localStorage.removeItem(localStorageName);
  867. pingSettings = {
  868. 'triggers': [],
  869. 'audioUrl': 'http://chat.rphaven.com/sounds/boop.mp3',
  870. 'color': '#000',
  871. 'highlight': '#FFA',
  872. 'bold': false,
  873. 'italics': false,
  874. 'exact': false,
  875. 'case': false,
  876. };
  877.  
  878. chatSettings = {
  879. 'showNames': true,
  880. 'noIcons': false,
  881. 'strictUrl': false,
  882. 'canCancel': false,
  883. 'autoJoin': false,
  884. 'session': false,
  885. 'favRooms': [],
  886. 'RoomSession': [],
  887. };
  888. PopulateSettings();
  889. };
  890.  
  891. var PopulateSettings = function() {
  892. ClearUsersDropLists('favUserList');
  893.  
  894. $('#pingNames').val(pingSettings.triggers);
  895. $('#pingURL').val(pingSettings.audioUrl);
  896. $('#pingTextColor').val(pingSettings.color);
  897. $('#pingHighlightColor').val(pingSettings.highlight);
  898. $('input#pingBoldEnable').prop("checked", pingSettings.bold);
  899. $('input#pingItalicsEnable').prop("checked", pingSettings.italics);
  900. $('input#pingExactMatch').prop("checked", pingSettings.exact);
  901. $('input#pingCaseSense').prop("checked", pingSettings.case);
  902.  
  903.  
  904. $('input#favEnable').prop("checked", chatSettings.autoJoin);
  905. $('input#showUsername').prop("checked", chatSettings.showNames);
  906. $('inputimgIconDisable').prop("checked", chatSettings.noIcons);
  907. $('#roomSessioning').prop("checked", chatSettings.session);
  908. $('#canCancelJoining').prop("checked", chatSettings.canCancel);
  909. $('#strictUrl').prop("checked", chatSettings.strictUrl);
  910.  
  911. for (var i = 0; i < chatSettings.favRooms.length; i++) {
  912. var favRoomObj = chatSettings.favRooms[i];
  913. $('#favRoomsList').append(
  914. '<option value="' + favRoomObj._id + '">' +
  915. favRoomObj.user + ": " + favRoomObj.room + '</option>'
  916. );
  917. }
  918.  
  919. if (chatSettings.favRooms.length >= 10) {
  920. $('#favAdd').text("Favorites Full");
  921. $('#favAdd')[0].disabled = true;
  922. }
  923.  
  924. pingSound = new Audio(pingSettings.audioUrl);
  925.  
  926. if (chatSettings.session) {
  927. updateSessionTimer = setInterval(updateSession, 30 * 1000);
  928. }
  929. };
  930.  
  931. /**************************************************************************
  932. * @brief Processes account events.
  933. *
  934. * @param account - Data blob countaining the user's account.
  935. **************************************************************************/
  936. var ProcessAccountEvt = function(account) {
  937. var users = account.users;
  938. ClearUsersDropLists('userColorDroplist');
  939. for (i = 0; i < users.length; i++) {
  940. AddUserToDroplist(users[i], 'userColorDroplist');
  941. AddUserToDroplist(users[i], 'favUserList');
  942. }
  943. };
  944.  
  945. var GetSettings = function() {
  946. return {
  947. 'chatSettings': chatSettings,
  948. 'pingSettings': pingSettings
  949. };
  950. };
  951.  
  952. return {
  953. init: function() {
  954. var autoJoining = false;
  955. var hasRooms = false;
  956. settingsDialog.chat = CreateDialog('#chatSettingsHeader', '#chatSettingsForm');
  957. settingsDialog.chat.button.click({
  958. dialog: settingsDialog.chat
  959. }, DialogToggle);
  960.  
  961. $('#pingNames').blur(function() {
  962. var triggers = $('#pingNames').val().replace('\n', '').replace('\r', '');
  963. pingSettings.triggers = triggers;
  964. SaveSettings();
  965. });
  966.  
  967. $('#pingURL').blur(function() {
  968. if (ValidateSetting('pingURL', 'url')) {
  969. pingSettings.audioUrl = GetInput('pingURL');
  970. SaveSettings();
  971. }
  972. });
  973.  
  974. $('#pingTextColor').blur(function() {
  975. if (ValidateSetting('pingTextColor', 'color')) {
  976. pingSettings.color = GetInput('pingTextColor');
  977. SaveSettings();
  978. }
  979. });
  980.  
  981. $('#pingHighlightColor').blur(function() {
  982. if (ValidateSetting('pingHighlightColor', 'color')) {
  983. pingSettings.highlight = GetInput('pingHighlightColor');
  984. SaveSettings();
  985. }
  986. });
  987.  
  988. $('#pingBoldEnable').change(function() {
  989. pingSettings.bold = GetCheckBox('pingBoldEnable');
  990. SaveSettings();
  991. });
  992.  
  993. $('#pingItalicsEnable').change(function() {
  994. pingSettings.italics = GetCheckBox('pingItalicsEnable');
  995. SaveSettings();
  996. });
  997.  
  998. $('#pingExactMatch').change(function() {
  999. pingSettings.exact = GetCheckBox('pingExactMatch');
  1000. SaveSettings();
  1001. });
  1002.  
  1003. $('#pingCaseSense').change(function() {
  1004. pingSettings.case = GetCheckBox('pingCaseSense');
  1005. SaveSettings();
  1006. });
  1007.  
  1008. $('#showUsername').change(function() {
  1009. chatSettings.showNames = GetCheckBox('showUsername');
  1010. SaveSettings();
  1011. });
  1012.  
  1013. $('#imgIconDisable').change(function() {
  1014. chatSettings.noIcons = GetCheckBox('imgIconDisable');
  1015. SaveSettings();
  1016. });
  1017.  
  1018. $('#favEnable').click(function() {
  1019. chatSettings.autoJoin = GetCheckBox('favEnable');
  1020. SaveSettings();
  1021. });
  1022.  
  1023. $('#roomSessioning').click(function() {
  1024. chatSettings.session = GetCheckBox('roomSessioning');
  1025.  
  1026. if (chatSettings.session) {
  1027. updateSessionTimer = setInterval(updateSession, 30 * 1000);
  1028. } else {
  1029. clearTimeout(updateSessionTimer);
  1030. }
  1031. SaveSettings();
  1032. });
  1033.  
  1034. $('#canCancelJoining').click(function() {
  1035. chatSettings.canCancel = GetCheckBox('canCancelJoining');
  1036. SaveSettings();
  1037. });
  1038.  
  1039. $('#strictUrl').click(function() {
  1040. chatSettings.strictUrl = GetCheckBox('strictUrl');
  1041. SaveSettings();
  1042. });
  1043.  
  1044. $('#favAdd').click(function() {
  1045. AddFavoriteRoom();
  1046. SaveSettings();
  1047. });
  1048.  
  1049. $('#favRemove').click(function() {
  1050. RemoveFavoriteRoom();
  1051. SaveSettings();
  1052. });
  1053.  
  1054. $('#userNameTextColorButton').click(function() {
  1055. ChangeTextColor();
  1056. });
  1057.  
  1058. $('#chatHistory').change(function() {
  1059. rph.setSetting('maxHistory', parseInt($(this).val()));
  1060. });
  1061.  
  1062. if (JSON.parse(localStorage.getItem(localStorageName))) {
  1063. LoadSettings(JSON.parse(localStorage.getItem(localStorageName)));
  1064. } else {
  1065. LoadOldSettings();
  1066. }
  1067.  
  1068. chatSocket.on('confirm-room-join', function(data) {
  1069. roomSetup(data);
  1070. });
  1071.  
  1072. chatSocket.on('user-kicked', function(data) {
  1073. for (var i = 0; i < account.users.length; i++) {
  1074. if (data.targetid == account.users[i]) {
  1075. $('<div class="inner"><p>You were kicked from ' +
  1076. data.room + '.<br />' + ' Reason: ' + data.msg +
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement