PageRenderTime 57ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/web/studio/ASC.Web.Studio/UserControls/Common/SmallChat/js/smallChat.js

https://github.com/DevExperience/ONLYOFFICE-Server
JavaScript | 2561 lines | 2352 code | 144 blank | 65 comment | 485 complexity | 5833df017fb0fde8a9ba44cedd27334e MD5 | raw file
Possible License(s): GPL-2.0, MPL-2.0-no-copyleft-exception

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. (c) Copyright Ascensio System SIA 2010-2014
  3. This program is a free software product.
  4. You can redistribute it and/or modify it under the terms
  5. of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
  6. Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
  7. to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
  8. any third-party rights.
  9. This program is distributed WITHOUT ANY WARRANTY; without even the implied warranty
  10. of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
  11. the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
  12. You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
  13. The interactive user interfaces in modified source and object code versions of the Program must
  14. display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
  15. Pursuant to Section 7(b) of the License you must retain the original Product logo when
  16. distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
  17. trademark law for use of our trademarks.
  18. All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
  19. content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
  20. International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
  21. */
  22. /*
  23. Copyright (c) Ascensio System SIA 2014. All rights reserved.
  24. http://www.teamlab.com
  25. */
  26. var SmallChat = (function () {
  27. var chat = jq.connection.c,
  28. currentAccount = null,
  29. already = false,
  30. bufferStates = {},
  31. offlineBuffer = [],
  32. ONLINE = "online",
  33. AWAY = "away",
  34. NOT_AVAILABLE = "not_available",
  35. OFFLINE = "offline",
  36. NUMBER_ONLINE = 1,
  37. NUMBER_AWAY = 2,
  38. NUMBER_NOT_AVAILABLE = 3,
  39. NUMBER_OFFLINE = 4,
  40. IMAGE_ONLINE = "image_online",
  41. IMAGE_AWAY = "image_away",
  42. IMAGE_NOT_AVAILABLE = "image_not_available",
  43. IMAGE_OFFLINE = "image_offline",
  44. PX = "px",
  45. HEIGHT_OFFSET = 100,
  46. OPEN_USER_DETAIL_LIST_INTERVAL = 650,
  47. PING_TIMEOUT_INTERVAL = 100000,
  48. INT_MAX_VALUE = 2147483647,
  49. SEARCH_CONTACT_INTERVAL = 750,
  50. TITLE_INTERVAL = 400,
  51. ENTER_KEY_CODE = 13,
  52. CONVERSATION_BLOCK_HEIGHT = 300,
  53. CONVERSATION_BLOCK_WIDTH = 282,
  54. LEFT_PANEL_AND_INDENT_WIDTH = 370,
  55. MESSAGE_WINDOW_ITEM_HEIGHT = 21,
  56. currentStatus = ONLINE,
  57. currentImage = IMAGE_ONLINE,
  58. NUMBER_OF_RECENT_MSGS = 10,
  59. oldWindowHeight = jq(window).height(),
  60. oldWindowWidth = jq(window).width(),
  61. originalTitle = null,
  62. isActive = false,
  63. titleTimerId = null,
  64. starsNumber = 1,
  65. soundPath = null,
  66. sendTypingSignalTimeout = null,
  67. typingSignalTimeout = null,
  68. shouldOpenUserDialogs = [],
  69. disableUser = false,
  70. timersForMessages = {},
  71. pingTimerId = null,
  72. flashBlocks = {},
  73. shouldOpenContacts = false,
  74. jabberTalkWindow = null,
  75. initEmoticons = false,
  76. maxDialogNumber = null,
  77. isMobile = jq.browser.mobile,
  78. connectionStartTimer = null,
  79. reloadPage = false,
  80. disconnectCompleted = true,
  81. messageContract = {
  82. i: "Id",
  83. u: "UserName",
  84. t: "Text",
  85. d: "DateTimeText"
  86. },
  87. userStrContract = {
  88. u: "UserName",
  89. d: "DisplayUserName",
  90. s: "State"
  91. },
  92. userInformations = {},
  93. sessionStorageManager = function () {
  94. var isAvailable;
  95. try {
  96. isAvailable = "sessionStorage" in window && window["sessionStorage"] !== null;
  97. } catch (e) {
  98. return { isAvailable: false };
  99. }
  100. var getItem = function (key) {
  101. if (!key) {
  102. return null;
  103. }
  104. return JSON.parse(sessionStorage.getItem(key));
  105. };
  106. var setItem = function (key, value) {
  107. if (!key) {
  108. return;
  109. }
  110. try {
  111. sessionStorage.setItem(key, JSON.stringify(value));
  112. } catch (e) {
  113. if (typeof QUOTA_EXCEEDED_ERR != undefined && e == QUOTA_EXCEEDED_ERR) {
  114. throw "Session storage is full";
  115. }
  116. }
  117. };
  118. var removeItem = function (key) {
  119. if (!key) {
  120. return null;
  121. }
  122. sessionStorage.removeItem(key);
  123. };
  124. var clear = function () {
  125. sessionStorage.clear();
  126. };
  127. return {
  128. isAvailable: isAvailable,
  129. getItem: getItem,
  130. setItem: setItem,
  131. removeItem: removeItem,
  132. clear: clear
  133. };
  134. }();
  135. localStorageManager = function () {
  136. var isAvailable;
  137. try {
  138. isAvailable = "localStorage" in window && window["localStorage"] !== null;
  139. } catch (e) {
  140. return { isAvailable: false };
  141. }
  142. var getItem = function (key) {
  143. if (!key) {
  144. return null;
  145. }
  146. return JSON.parse(localStorage.getItem(key));
  147. };
  148. var setItem = function (key, value) {
  149. if (!key) {
  150. return;
  151. }
  152. try {
  153. localStorage.setItem(key, JSON.stringify(value));
  154. } catch (e) {
  155. if (typeof QUOTA_EXCEEDED_ERR != undefined && e == QUOTA_EXCEEDED_ERR) {
  156. throw "Local storage is full";
  157. }
  158. }
  159. };
  160. var removeItem = function (key) {
  161. if (!key) {
  162. return null;
  163. }
  164. localStorage.removeItem(key);
  165. };
  166. var clear = function () {
  167. localStorage.clear();
  168. };
  169. return {
  170. isAvailable: isAvailable,
  171. getItem: getItem,
  172. setItem: setItem,
  173. removeItem: removeItem,
  174. clear: clear
  175. };
  176. }();
  177. if (Teamlab.profile.id && sessionStorageManager.getItem("currentUserId") != Teamlab.profile.id) {
  178. sessionStorageManager.clear();
  179. sessionStorageManager.setItem("currentUserId", Teamlab.profile.id);
  180. }
  181. if (typeof (chat) !== undefined) {
  182. // initDataRetrieved
  183. chat.client.idr = function (userName, showUserName, users, tenantId, tenantName, path) {
  184. currentAccount = {
  185. TenantName: tenantName,
  186. TenantId: tenantId,
  187. UserName: userName,
  188. ShowUserName: showUserName
  189. };
  190. soundPath = path;
  191. var $userList = jq(".user_list"),
  192. usersOnline = {},
  193. usersAway = {},
  194. usersNotAvailable = {},
  195. usersOffline = {},
  196. stateNumber;
  197. if ($userList.length) {
  198. jq(".user_list").remove();
  199. }
  200. for (var i = 0; i < users.length; i++) {
  201. users[i] = reMap(users[i], userStrContract);
  202. stateNumber = users[i].State;
  203. users[i].State = getImageByNumber(stateNumber);
  204. switch (stateNumber) {
  205. case NUMBER_ONLINE:
  206. usersOnline[i] = users[i];
  207. break;
  208. case NUMBER_AWAY:
  209. usersAway[i] = users[i];
  210. break;
  211. case NUMBER_NOT_AVAILABLE:
  212. usersNotAvailable[i] = users[i];
  213. break;
  214. default:
  215. usersOffline[i] = users[i];
  216. }
  217. }
  218. var tenantGuid = sessionStorageManager.getItem("TenantGuid");
  219. if (!tenantGuid) {
  220. tenantGuid = guid();
  221. sessionStorageManager.setItem("TenantGuid", tenantGuid);
  222. }
  223. var html = jq("#contactListTmpl").tmpl({
  224. UsersOnline: usersOnline,
  225. UsersAway: usersAway,
  226. UsersNotAvailable: usersNotAvailable,
  227. UsersOffline: usersOffline
  228. }),
  229. htmlTenant = jq("#tenantBlockTmpl").tmpl({
  230. TenantGuid: tenantGuid,
  231. TenantName: currentAccount.TenantName
  232. }),
  233. smallChatHeight = sessionStorageManager.getItem("SmallChatHeight");
  234. if (smallChatHeight) {
  235. jq(".small_chat_main_window").css("height", smallChatHeight);
  236. }
  237. jq(".chat_contact_loader").addClass("display-none");
  238. jq(".conversation_block").removeClass("display-none");
  239. jq(html).appendTo(".contact_container");
  240. jq(".contact_container").find(".tenant_user_list").append(htmlTenant);
  241. sessionStorageManager.setItem("WasConnected", true);
  242. searchContact();
  243. var status = sessionStorageManager.getItem("CurrentStatus");
  244. if (status && status != OFFLINE) {
  245. changeStatus(getUserNumberByState(status));
  246. }
  247. for (var un in bufferStates) {
  248. setState(un, bufferStates[un]);
  249. }
  250. bufferStates = {};
  251. for (var i = 0; i < offlineBuffer.length; i++) {
  252. if (offlineBuffer[i] == "") {
  253. offlineBuffer[i] = sessionStorageManager.getItem("TenantGuid");
  254. }
  255. if (isDialogOpen(offlineBuffer[i])) {
  256. closeConversationBlock(offlineBuffer[i]);
  257. }
  258. removeUserInSessionIfExists(offlineBuffer[i]);
  259. openMessageDialog(offlineBuffer[i]);
  260. var result = flashConversationBlock(offlineBuffer[i], true);
  261. if (result) {
  262. flashBlocks[offlineBuffer[i]] = result;
  263. }
  264. }
  265. offlineBuffer = [];
  266. loadMessageDialogs();
  267. jq(".extend_chat_icon").off("click").on("click", extendChat);
  268. ASC.Controls.JabberClient.extendChat = extendChat;
  269. setPingSending();
  270. };
  271. // sendInvite
  272. chat.client.si = function (message) {
  273. message = reMap(message, messageContract);
  274. if (!isDialogOpen(sessionStorageManager.getItem("TenantGuid"))) {
  275. openMessageDialog(sessionStorageManager.getItem("TenantGuid"));
  276. }
  277. putMessage({
  278. IsMessageOfCurrentUser: false,
  279. Name: message.UserName,
  280. DateTime: Teamlab.getDisplayTime(new Date()),
  281. Message: addBr(ASC.Resources.Master.ChatResource.ChatRoomInvite + " " + message.Text + ". " + ASC.Resources.Master.ChatResource.GoTalk),
  282. NotRead: true
  283. }, sessionStorageManager.getItem("TenantGuid"));
  284. };
  285. // send
  286. chat.client.s = function (message, calleeUserName, isTenantUser) {
  287. message = reMap(message, messageContract);
  288. if (currentAccount != null) {
  289. var userName = undefined,
  290. showUserName = undefined,
  291. $document = jq(document),
  292. isMessageOfCurrentUser = undefined;
  293. if (!isTenantUser) {
  294. userName = message.UserName;
  295. isMessageOfCurrentUser = (userName == currentAccount.UserName);
  296. showUserName = isMessageOfCurrentUser ?
  297. currentAccount.ShowUserName :
  298. jq(".contact_block[data-username='" + message.UserName + "']").find(".contact_record").text();
  299. } else {
  300. userName = sessionStorageManager.getItem("TenantGuid");
  301. showUserName = currentAccount.TenantName;
  302. isMessageOfCurrentUser = (userName == currentAccount.UserName);
  303. }
  304. var realUserName = isMessageOfCurrentUser ? calleeUserName : userName;
  305. if (isDialogOpen(userName) || isDialogOpen(calleeUserName)) {
  306. if (!isMessageOfCurrentUser) {
  307. var $conversationBlock = jq(".conversation_block[data-username='" + userName + "']");
  308. hideTypingMessageNotification($conversationBlock, $conversationBlock.find(".message_bus_container"));
  309. }
  310. putMessage({
  311. IsMessageOfCurrentUser: isMessageOfCurrentUser,
  312. Name: showUserName,
  313. DateTime: Teamlab.getDisplayTime(new Date()),
  314. Message: addBr(message.Text),
  315. NotRead: !isMessageOfCurrentUser
  316. }, realUserName);
  317. } else if (isActive && !isMessageOfCurrentUser) {
  318. showMessageNotification({
  319. UserName: userName,
  320. Message: addBr(message.Text),
  321. ShowUserName: showUserName,
  322. });
  323. }
  324. if (!isMessageOfCurrentUser) {
  325. if (!isMobile && soundPath && localStorageManager.getItem("EnableSound")) {
  326. playSound(soundPath);
  327. }
  328. if (!isActive) {
  329. shouldOpenUserDialogs[shouldOpenUserDialogs.length] = userName;
  330. if (!titleTimerId) {
  331. originalTitle = $document.find("title").text();
  332. $document.find("title").text("*" + ASC.Resources.Master.ChatResource.NewMessageLabel + " " + originalTitle);
  333. titleTimerId = setInterval(function () {
  334. starsNumber++;
  335. $document.find("title").text(getStars(starsNumber) +
  336. ASC.Resources.Master.ChatResource.NewMessageLabel + " " + originalTitle);
  337. if (starsNumber == 3) {
  338. starsNumber = 0;
  339. }
  340. }, TITLE_INTERVAL);
  341. }
  342. }
  343. } else {
  344. openMessageDialog(calleeUserName);
  345. }
  346. }
  347. };
  348. // sendOfflineMessages
  349. chat.client.som = function (userNames) {
  350. offlineBuffer = userNames;
  351. if (currentAccount && sessionStorageManager.getItem("WasConnected")) {
  352. for (var i = 0; i < offlineBuffer.length; i++) {
  353. if (offlineBuffer[i] == "") {
  354. offlineBuffer[i] = sessionStorageManager.getItem("TenantGuid");
  355. }
  356. if (isDialogOpen(offlineBuffer[i])) {
  357. closeConversationBlock(offlineBuffer[i]);
  358. }
  359. removeUserInSessionIfExists(offlineBuffer[i]);
  360. openMessageDialog(offlineBuffer[i]);
  361. var result = flashConversationBlock(offlineBuffer[i], true);
  362. if (result) {
  363. flashBlocks[offlineBuffer[i]] = result;
  364. }
  365. }
  366. offlineBuffer = [];
  367. }
  368. };
  369. // sendTypingSignal
  370. chat.client.sts = function (userName) {
  371. if (isDialogOpen(userName)) {
  372. var $conversationBlock = jq(".conversation_block[data-username='" + userName + "']"),
  373. $typingMessageNotification = $conversationBlock.find(".typing_message_notification");
  374. if ($typingMessageNotification.hasClass("display-none")) {
  375. $messageBusContainer = $conversationBlock.find(".message_bus_container");
  376. $typingMessageNotification.css("bottom", $conversationBlock.find(".message_input_area").outerHeight() + PX);
  377. $typingMessageNotification.removeClass("display-none");
  378. }
  379. if (typingSignalTimeout) {
  380. clearTimeout(typingSignalTimeout);
  381. typingSignalTimeout = null;
  382. }
  383. typingSignalTimeout = setTimeout(function () {
  384. hideTypingMessageNotification($conversationBlock, $conversationBlock.find(".message_bus_container"));
  385. }, 5000);
  386. }
  387. };
  388. // setState
  389. chat.client.ss = function (userName, stateNumber, isJabberClient) {
  390. if (currentAccount != null) {
  391. setState(userName, stateNumber, isJabberClient);
  392. } else {
  393. bufferStates[userName] = stateNumber;
  394. }
  395. };
  396. // statesRetrieved
  397. chat.client.sr = function (states) {
  398. var keys = Object.keys(states),
  399. status = sessionStorageManager.getItem("CurrentStatus"),
  400. $conversationBlocks = jq(".conversation_block"),
  401. $chatMessagesLoading,
  402. $conversationBlock;
  403. $conversationBlocks.removeClass("display-none");
  404. for (var i = 0; i < keys.length; i++) {
  405. setState(keys[i], states[keys[i]]);
  406. }
  407. sessionStorageManager.setItem("WasConnected", true);
  408. for (var i = 0; i < $conversationBlocks.length; i++) {
  409. $conversationBlock = jq($conversationBlocks[i]);
  410. if (!$conversationBlock.find(".chat_messages_loading").hasClass("display-none")) {
  411. getRecentMessagesOnStart($conversationBlock.attr("data-username"));
  412. }
  413. }
  414. if (status && status != OFFLINE) {
  415. changeStatus(getUserNumberByState(status));
  416. }
  417. for (var userName in bufferStates) {
  418. setState(userName, bufferStates[userName]);
  419. }
  420. searchContact();
  421. bufferStates = {};
  422. for (var i = 0; i < offlineBuffer.length; i++) {
  423. if (offlineBuffer[i] == "") {
  424. offlineBuffer[i] = sessionStorageManager.getItem("TenantGuid");
  425. }
  426. if (isDialogOpen(offlineBuffer[i])) {
  427. closeConversationBlock(offlineBuffer[i]);
  428. }
  429. openMessageDialog(offlineBuffer[i]);
  430. var result = flashConversationBlock(offlineBuffer[i], true);
  431. if (result) {
  432. flashBlocks[offlineBuffer[i]] = result;
  433. }
  434. }
  435. offlineBuffer = [];
  436. jq(".extend_chat_icon").off("click").on("click", extendChat);
  437. ASC.Controls.JabberClient.extendChat = extendChat;
  438. setPingSending();
  439. };
  440. // setStatus
  441. chat.client.sst = function (number) {
  442. changeStatus(number);
  443. };
  444. // error
  445. chat.client.e = function () {
  446. showErrorNotification();
  447. connectionStop();
  448. closeChat();
  449. };
  450. } else {
  451. throw "Error! Chat proxy is undefined!!!";
  452. }
  453. function getRecentMessagesOnStart(u) {
  454. var userName = u;
  455. chat.server.grm(userName == sessionStorageManager.getItem("TenantGuid") ? "" : userName, INT_MAX_VALUE).done(function (recentMessages) {
  456. var $cb = jq(".conversation_block[data-username='" + userName + "']"),
  457. $chatLoading = $cb.find(".chat_messages_loading");
  458. receiveRecentMessages(userName, recentMessages, $chatLoading, $cb, 0);
  459. });
  460. }
  461. function removeUserInSessionIfExists(currentUserName) {
  462. var dialogsNumber = sessionStorageManager.getItem("dialogsNumber");
  463. for (var i = 0; i < dialogsNumber; i++) {
  464. if (currentUserName == sessionStorageManager.getItem("userName" + i)) {
  465. for (var j = i; j < dialogsNumber; j++) {
  466. sessionStorageManager.setItem("userName" + j, sessionStorageManager.getItem("userName" + (j + 1)));
  467. }
  468. sessionStorageManager.removeItem("userName" + dialogsNumber - 1);
  469. sessionStorageManager.setItem("dialogsNumber", dialogsNumber - 1);
  470. break;
  471. }
  472. }
  473. }
  474. function s4() {
  475. return (0 | ((1 + Math.random()) * 0x10000)).toString(16).substring(1);
  476. }
  477. function guid() {
  478. return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
  479. }
  480. function setPingSending() {
  481. if (pingTimerId) {
  482. clearInterval(pingTimerId);
  483. }
  484. pingTimerId = setInterval(function () {
  485. if (sessionStorageManager.getItem("WasConnected")) {
  486. // ping
  487. chat.server.p();
  488. } else {
  489. clearInterval(pingTimerId);
  490. pingTimerId = null;
  491. }
  492. }, PING_TIMEOUT_INTERVAL);
  493. }
  494. function hideTypingMessageNotification(conversationBlock, messageBusContainer) {
  495. jq(conversationBlock).find(".typing_message_notification").addClass("display-none");
  496. jq(messageBusContainer).css({ "height": "100%", "padding-bottom": "0" });
  497. if (typingSignalTimeout) {
  498. clearTimeout(typingSignalTimeout);
  499. typingSignalTimeout = null;
  500. }
  501. }
  502. function getStars(starsNumber) {
  503. switch (starsNumber) {
  504. case 1: return "*";
  505. case 2: return "**";
  506. case 3: return "***";
  507. }
  508. }
  509. function loadMessageDialogs() {
  510. var userName,
  511. dialogsNumber = sessionStorageManager.getItem("dialogsNumber"),
  512. dialogsNumberInMenu = sessionStorageManager.getItem("dialogsNumberInMenu");
  513. if (dialogsNumber) {
  514. for (var i = 0; i < dialogsNumber; i++) {
  515. userName = sessionStorageManager.getItem("userName" + i);
  516. openMessageDialog(userName, true, i);
  517. // if user was disabled
  518. if (disableUser) {
  519. i--;
  520. dialogsNumber--;
  521. disableUser = false;
  522. }
  523. if (sessionStorageManager.getItem("MiniCB" + userName)) {
  524. minimize(jq(".conversation_block[data-username='" + userName + "']"));
  525. }
  526. }
  527. }
  528. if (dialogsNumberInMenu) {
  529. for (var i = 0; i < dialogsNumberInMenu; i++) {
  530. userName = sessionStorageManager.getItem("dn_userName" + i);
  531. var $contactRecord = jq(".contact_block[data-username='" + userName + "']").find(".contact_record");
  532. // if user was disabled
  533. if (!$contactRecord.length) {
  534. sessionStorageManager.setItem("dialogsNumberInMenu", dialogsNumberInMenu - 1);
  535. for (var j = i; j < dialogsNumberInMenu - 1; j++) {
  536. sessionStorageManager.setItem("dn_userName" + j, sessionStorageManager.getItem("dn_userName" + (j + 1)));
  537. }
  538. sessionStorageManager.removeItem("dn_userName" + (dialogsNumberInMenu - 1));
  539. i--;
  540. dialogsNumberInMenu--;
  541. continue;
  542. }
  543. addToMenu({
  544. UserName: userName,
  545. ShowUserName: $contactRecord.text(),
  546. }, true);
  547. }
  548. // if user was disabled
  549. if (getMaxDialogNumber() > sessionStorageManager.getItem("dialogsNumber")) {
  550. userName = jq("#messageDialogPopupID").find(".message_dialog_item").first().attr("data-username");
  551. closeMessageDialogItem(userName);
  552. openMessageDialog(userName);
  553. }
  554. }
  555. jq(".message_input_area").blur();
  556. }
  557. function isDialogOpen(userName) {
  558. if (jq(".conversation_block[data-username='" + userName + "']").length) {
  559. return true;
  560. }
  561. return false;
  562. }
  563. function isDialogInMenu(userName) {
  564. if (jq(".message_dialog_item[data-username='" + userName + "']").length) {
  565. return true;
  566. }
  567. return false;
  568. }
  569. function removeParametersOfDialogInMenu(userName) {
  570. var $block = jq(".message_dialog_item[data-username='" + userName + "']"),
  571. $items = jq(".message_dialog_item"),
  572. dialogsNumberInMenu = sessionStorageManager.getItem("dialogsNumberInMenu") - 1,
  573. $messageDialogItem = jq(".message_dialog_item");
  574. for (var i = 0; i < $messageDialogItem.length; i++) {
  575. var nextIndex = $items.index($messageDialogItem[i]);
  576. if ($items.index($block) < nextIndex) {
  577. sessionStorageManager.setItem("dn_userName" + (nextIndex - 1),
  578. sessionStorageManager.getItem("dn_userName" + nextIndex));
  579. }
  580. }
  581. $block.remove();
  582. sessionStorageManager.removeItem("dn_userName" + dialogsNumberInMenu);
  583. sessionStorageManager.setItem("dialogsNumberInMenu", dialogsNumberInMenu);
  584. }
  585. function setParametersOfDialog(userName) {
  586. var dialogsNumber = sessionStorageManager.getItem("dialogsNumber");
  587. if (dialogsNumber) {
  588. sessionStorageManager.setItem("userName" + dialogsNumber, userName);
  589. jq(".conversation_block[data-username='" + userName + "']").attr("data-dialog-number", dialogsNumber);
  590. sessionStorageManager.setItem("dialogsNumber", ++dialogsNumber);
  591. } else {
  592. sessionStorageManager.setItem("userName0", userName);
  593. jq(".conversation_block[data-username='" + userName + "']").attr("data-dialog-number", "0");
  594. sessionStorageManager.setItem("dialogsNumber", 1);
  595. }
  596. }
  597. function setParametersOfDialogInMenu(userName) {
  598. var dialogsNumberInMenu = sessionStorageManager.getItem("dialogsNumberInMenu");
  599. if (dialogsNumberInMenu) {
  600. sessionStorageManager.setItem("dn_userName" + dialogsNumberInMenu, userName);
  601. sessionStorageManager.setItem("dialogsNumberInMenu", ++dialogsNumberInMenu);
  602. } else {
  603. sessionStorageManager.setItem("dn_userName0", userName);
  604. sessionStorageManager.setItem("dialogsNumberInMenu", 1);
  605. }
  606. }
  607. function getContactNumberBeforeCurrent(name, ulClass) {
  608. var $lists = jq("." + ulClass).children();
  609. for (var i = 0; i < $lists.length; i++) {
  610. if (name <= jq($lists[i]).find(".contact_record").text().toLowerCase()) {
  611. break;
  612. }
  613. }
  614. return i;
  615. }
  616. function setState(userName, stateNumber, isJabberClient) {
  617. if (userName != currentAccount.UserName) {
  618. var newState = getImageByNumber(stateNumber),
  619. $contactBlock = jq(".contact_block[data-username='" + userName + "']"),
  620. ulClass;
  621. if ($contactBlock.length) {
  622. var $elem = $contactBlock.find(".chat_user_state");
  623. if ($elem.attr("class") != undefined) {
  624. var oldState = $elem.attr("class").split(" ")[1];
  625. $elem.removeClass(oldState);
  626. $elem.addClass(newState);
  627. $contactBlock.detach();
  628. switch (stateNumber) {
  629. case NUMBER_ONLINE:
  630. ulClass = "online_user_list";
  631. break;
  632. case NUMBER_AWAY:
  633. ulClass = "away_user_list";
  634. break;
  635. case NUMBER_NOT_AVAILABLE:
  636. ulClass = "not_available_user_list";
  637. break;
  638. default:
  639. ulClass = "offline_user_list";
  640. }
  641. var contactNumber = getContactNumberBeforeCurrent($contactBlock.find(".contact_record").text().toLowerCase(), ulClass);
  642. if (contactNumber) {
  643. $contactBlock.insertAfter("." + ulClass + " li:nth-child(" + contactNumber + ")");
  644. } else {
  645. $contactBlock.prependTo("." + ulClass);
  646. }
  647. }
  648. } else {
  649. if (sessionStorageManager.getItem("WasConnected")) {
  650. // getContactInfo
  651. chat.server.gci(userName).done(function (contact) {
  652. switch (contact.Item2) {
  653. case NUMBER_ONLINE:
  654. ulClass = "online_user_list";
  655. break;
  656. case NUMBER_AWAY:
  657. ulClass = "away_user_list";
  658. break;
  659. case NUMBER_NOT_AVAILABLE:
  660. ulClass = "not_available_user_list";
  661. break;
  662. default:
  663. ulClass = "offline_user_list";
  664. }
  665. createContactInfo({
  666. UserName: userName,
  667. ShowUserName: contact.Item1,
  668. StateClass: ulClass
  669. }, ulClass);
  670. }).fail(function (error) {
  671. showErrorNotification();
  672. });
  673. }
  674. }
  675. if (isDialogOpen(userName)) {
  676. var $stateBlock = jq(".conversation_block[data-username='" + userName + "']").find(".conversation_block_user_state");
  677. if ($stateBlock.attr("class") != undefined) {
  678. var oldState = $stateBlock.attr("class").split(" ")[1];
  679. $stateBlock.removeClass(oldState);
  680. $stateBlock.addClass(newState);
  681. $stateBlock.attr("title", getRealStateByNumber(stateNumber));
  682. }
  683. }
  684. } else if (!isJabberClient) {
  685. changeStatus(stateNumber);
  686. }
  687. }
  688. function createContactInfo(contact, ulClass) {
  689. var contactNumber = getContactNumberBeforeCurrent(contact.UserName, ulClass),
  690. html = jq("#contactTmpl").tmpl(contact);
  691. if (contactNumber) {
  692. html.insertAfter("." + ulClass + " li:nth-child(" + contactNumber + ")");
  693. } else {
  694. html.prependTo("." + ulClass);
  695. }
  696. }
  697. function changeStatus(stateNumber, NoIconGreen) {
  698. var state = getUserStateByNumber(stateNumber);
  699. if (state != currentStatus) {
  700. var prevStatus = currentStatus,
  701. $showSmallChatIcon = jq(".show_small_chat_icon"),
  702. $smallChatPopupID = jq("#smallChatPopupID"),
  703. $smallChatTextStatus = jq(".small_chat_text_status"),
  704. $currentStatus = jq("." + currentStatus),
  705. realStatus;
  706. $smallChatPopupID.removeClass("display_block");
  707. $smallChatPopupID.addClass("display-none");
  708. $currentStatus.removeClass("disable");
  709. $smallChatTextStatus.removeClass(currentImage);
  710. $currentStatus.click(chooseStatus);
  711. if (state == OFFLINE) {
  712. $showSmallChatIcon.addClass("small_chat_icon_white");
  713. $showSmallChatIcon.removeClass("small_chat_icon_green");
  714. connectionStop();
  715. } else if (!NoIconGreen) {
  716. $showSmallChatIcon.addClass("small_chat_icon_green");
  717. $showSmallChatIcon.removeClass("small_chat_icon_white");
  718. }
  719. currentImage = getImageByNumber(stateNumber);
  720. currentStatus = state;
  721. sessionStorageManager.setItem("CurrentStatus", currentStatus);
  722. $currentStatus = jq("." + currentStatus);
  723. $currentStatus.off("click");
  724. $currentStatus.addClass("disable");
  725. $smallChatTextStatus.addClass(currentImage);
  726. realStatus = getRealState(currentStatus);
  727. $smallChatTextStatus.text(realStatus);
  728. jq("small_chat_status_menu").attr("title", realStatus);
  729. }
  730. }
  731. function showMessageNotification(object) {
  732. noty({
  733. text: jq("#messageNotificationTmpl").tmpl(object),
  734. layout: "bottomRight",
  735. theme: "defaultTheme",
  736. type: "alert",
  737. animation: {
  738. easing: "swing",
  739. open: { "height": "toggle" },
  740. close: { "height": "toggle" },
  741. speed: "400",
  742. },
  743. timeout: "7000",
  744. maxVisible: 7,
  745. force: true
  746. });
  747. }
  748. function putMessage(object, userName) {
  749. var $conversationBlock = jq(".conversation_block[data-username='" + userName + "']"),
  750. $messageBusContainer = $conversationBlock.find(".message_bus_container"),
  751. $last = $messageBusContainer.find(".message_of_user:last");
  752. if ((($last.hasClass("message_of_other_user") && object.IsMessageOfCurrentUser) ||
  753. ($last.hasClass("message_of_current_user") && !object.IsMessageOfCurrentUser)) &&
  754. timersForMessages[userName]) {
  755. clearTimeout(timersForMessages[userName]);
  756. delete timersForMessages[userName];
  757. }
  758. if (!object.IsMessageOfCurrentUser && !(userName in flashBlocks)) {
  759. var result = flashConversationBlock(userName, true);
  760. if (result) {
  761. flashBlocks[userName] = result;
  762. }
  763. }
  764. if (!timersForMessages[userName]) {
  765. $messageBusContainer.append(jq("#messageTmpl").tmpl(object));
  766. $last = $messageBusContainer.find(".message_of_user:last");
  767. } else {
  768. $last.next().text(object.DateTime);
  769. $last.after("<div class='message_of_user " +
  770. ($last.hasClass("message_of_current_user") ? "message_of_current_user" : "message_of_other_user not_read_message") +
  771. "'>" + object.Message + "</div>");
  772. clearTimeout(timersForMessages[userName]);
  773. delete timersForMessages[userName];
  774. }
  775. timersForMessages[userName] = setTimeout(function () {
  776. clearTimeout(timersForMessages[userName]);
  777. delete timersForMessages[userName];
  778. }, 30000);
  779. $last = $messageBusContainer.find(".message_of_user:last");
  780. if (userName != sessionStorageManager.getItem("TenantGuid")) {
  781. emoticonize($last);
  782. }
  783. $last.linkify();
  784. scrollTopMessageContainer($messageBusContainer);
  785. }
  786. function scrollTopMessageContainer(messageBusContainer) {
  787. var $messageBusContainer = jq(messageBusContainer);
  788. scrollHeight = $messageBusContainer.prop("scrollHeight");
  789. if (scrollHeight > $messageBusContainer.scrollTop() && scrollHeight > $messageBusContainer.height()) {
  790. $messageBusContainer.scrollTop(scrollHeight);
  791. }
  792. }
  793. function putSmileInMessage(e) {
  794. var $smile = jq(e.currentTarget),
  795. $smileMenu = jq(".smile_menu"),
  796. dn = $smileMenu.attr("id").split("smilesPopupID")[1],
  797. $conversationBlock = jq(".conversation_block[data-dialog-number='" + dn + "']"),
  798. $messageInputArea = $conversationBlock.find(".message_input_area"),
  799. cursorPos = $messageInputArea.prop("selectionStart"),
  800. v = $messageInputArea.val(),
  801. smileString = " " + $smile.text();
  802. $messageInputArea.val(v.substring(0, cursorPos) + smileString + v.substring(cursorPos, v.length));
  803. $messageInputArea.val($messageInputArea.val() + " ");
  804. setCaretPosition($messageInputArea, cursorPos + smileString.length);
  805. $messageInputArea.trigger("autosize.resize");
  806. $messageInputArea.scrollTop($messageInputArea.prop("scrollHeight"));
  807. sendTypingSignal($conversationBlock.attr("data-username"));
  808. $smileMenu.css("display", "none");
  809. }
  810. function getRealState(state) {
  811. switch (state) {
  812. case ONLINE:
  813. return ASC.Resources.Master.ChatResource.StatusOnline;
  814. case AWAY:
  815. return ASC.Resources.Master.ChatResource.StatusAway;
  816. case NOT_AVAILABLE:
  817. return ASC.Resources.Master.ChatResource.StatusNA;
  818. default:
  819. return ASC.Resources.Master.ChatResource.StatusOffline;
  820. }
  821. }
  822. function getRealStateByNumber(stateNumber) {
  823. switch (stateNumber) {
  824. case NUMBER_ONLINE:
  825. return ASC.Resources.Master.ChatResource.StatusOnline;
  826. case NUMBER_AWAY:
  827. return ASC.Resources.Master.ChatResource.StatusAway;
  828. case NUMBER_NOT_AVAILABLE:
  829. return ASC.Resources.Master.ChatResource.StatusNA;
  830. default:
  831. return ASC.Resources.Master.ChatResource.StatusOffline;
  832. }
  833. }
  834. function getRealStateByImageState(stateNumber) {
  835. switch (stateNumber) {
  836. case IMAGE_ONLINE:
  837. return ASC.Resources.Master.ChatResource.StatusOnline;
  838. case IMAGE_AWAY:
  839. return ASC.Resources.Master.ChatResource.StatusAway;
  840. case IMAGE_NOT_AVAILABLE:
  841. return ASC.Resources.Master.ChatResource.StatusNA;
  842. default:
  843. return ASC.Resources.Master.ChatResource.StatusOffline;
  844. }
  845. }
  846. function getUserStateByImageState(imageState) {
  847. switch (imageState) {
  848. case IMAGE_ONLINE:
  849. return ONLINE;
  850. case IMAGE_AWAY:
  851. return AWAY;
  852. case IMAGE_NOT_AVAILABLE:
  853. return NOT_AVAILABLE;
  854. default:
  855. return OFFLINE;
  856. }
  857. }
  858. function getImageByNumber(stateNumber) {
  859. switch (stateNumber) {
  860. case NUMBER_ONLINE:
  861. return IMAGE_ONLINE;
  862. case NUMBER_AWAY:
  863. return IMAGE_AWAY;
  864. case NUMBER_NOT_AVAILABLE:
  865. return IMAGE_NOT_AVAILABLE;
  866. default:
  867. return IMAGE_OFFLINE;
  868. }
  869. }
  870. function getUserStateByNumber(stateNumber) {
  871. switch (stateNumber) {
  872. case NUMBER_ONLINE:
  873. return ONLINE;
  874. case NUMBER_AWAY:
  875. return AWAY;
  876. case NUMBER_NOT_AVAILABLE:
  877. return NOT_AVAILABLE;
  878. default:
  879. return OFFLINE;
  880. }
  881. }
  882. function getUserNumberByState(state) {
  883. switch (state) {
  884. case ONLINE:
  885. return NUMBER_ONLINE;
  886. case AWAY:
  887. return NUMBER_AWAY;
  888. case NOT_AVAILABLE:
  889. return NUMBER_NOT_AVAILABLE;
  890. default:
  891. return NUMBER_OFFLINE;
  892. }
  893. }
  894. function getUserNumberByStateForConnection() {
  895. var state = getUserNumberByState(sessionStorageManager.getItem("CurrentStatus"));
  896. if (!state || state == NUMBER_OFFLINE) {
  897. state = NUMBER_ONLINE;
  898. }
  899. return state;
  900. }
  901. function openUserDetailList(e) {
  902. if (isMobile) {
  903. return;
  904. }
  905. closeUserDetailList();
  906. if (sessionStorageManager.getItem("WasConnected")) {
  907. var $contactBlock = jq(e.currentTarget),
  908. userName = $contactBlock.attr("data-username");
  909. if (!$contactBlock.is(":hover") || userName == sessionStorageManager.getItem("TenantGuid")) {
  910. return;
  911. }
  912. var timeoutId = setTimeout(function () {
  913. if (!$contactBlock.is(":hover") || !sessionStorageManager.getItem("WasConnected")) {
  914. return;
  915. }
  916. var $detailUserList = jq(".detail_user_list");
  917. if ($detailUserList.length) {
  918. $detailUserList.remove();
  919. }
  920. if (userInformations[userName]) {
  921. openDetail(userName, userInformations[userName], $contactBlock);
  922. } else {
  923. Teamlab.getProfile({}, userName, {
  924. success: function (params, data) {
  925. var departments = {};
  926. if (data.groups) {
  927. for (var i = 0; i < data.groups.length; i++) {
  928. departments[data.groups[i].id] = data.groups[i].name;
  929. }
  930. }
  931. userInformation = {
  932. UserName: userName,
  933. ShowUserName: data.displayName,
  934. Email: data.email,
  935. UserType: data.isVisitor ? ASC.Resources.Master.Guest : ASC.Resources.Master.User,
  936. Title: data.title,
  937. PhotoURL: data.avatar,
  938. Departments: departments
  939. };
  940. userInformations[userName] = userInformation;
  941. openDetail(userName, userInformation, $contactBlock);
  942. }
  943. });
  944. }
  945. }, OPEN_USER_DETAIL_LIST_INTERVAL);
  946. $contactBlock.data("timeoutId", timeoutId);
  947. }
  948. }
  949. function openDetail(userName, data, $contactBlock) {
  950. if (!jq($contactBlock).is(":hover")) {
  951. return;
  952. }
  953. if (data) {
  954. var html = jq("#detailUserListTmpl").tmpl(data),
  955. $detailUserList = jq(html).appendTo(".mainPageTableSidePanel"),
  956. positionOfContact = jq(".contact_block[data-username='" + userName + "']").offset(),
  957. top = positionOfContact.top - 30,
  958. $window = jq(window),
  959. scrollTop = $window.scrollTop();
  960. $detailUserList.css("left", positionOfContact.left + 220 + PX);
  961. if (top + $detailUserList.outerHeight(true) < $window.height() + scrollTop) {
  962. $detailUserList.css("top", top - scrollTop + PX);
  963. } else {
  964. $detailUserList.css("bottom", 15 + PX);
  965. }
  966. $detailUserList.fadeIn(170);
  967. $detailUserList.removeClass("display-none");
  968. }
  969. }
  970. function closeUserDetailList(e) {
  971. if (isMobile) {
  972. return;
  973. }
  974. if (sessionStorageManager.getItem("WasConnected")) {
  975. setTimeout(function () {
  976. var $detailUserList = jq(".detail_user_list");
  977. if (e) {
  978. clearTimeout(jq(e.currentTarget).data("timeoutId"));
  979. }
  980. if ($detailUserList.length && !$detailUserList.hasClass("hover")) {
  981. $detailUserList.fadeOut(100);
  982. }
  983. }, 50);
  984. }
  985. }
  986. function showChat() {
  987. var smallChatHeight = sessionStorageManager.getItem("SmallChatHeight"),
  988. $showSmallChatIcon = jq(".show_small_chat_icon"),
  989. $smallChatMainWindow = jq(".small_chat_main_window");
  990. jq(".extend_chat_icon").off("click");
  991. ASC.Controls.JabberClient.extendChat = function () { ASC.Controls.JabberClient.open(); }
  992. sessionStorageManager.setItem("WasLoad", true);
  993. $smallChatMainWindow.addClass("small_chat_main_window_full");
  994. $showSmallChatIcon.addClass("small_chat_icon_green");
  995. $showSmallChatIcon.removeClass("small_chat_icon_white");
  996. jq(".contact_container").removeClass("display-none");
  997. jq(".small_chat_top_panel").removeClass("display-none");
  998. jq(".icon_ch_size").removeClass("display-none");
  999. resizeChat();
  1000. jq(".conversation_block").removeClass("display-none");
  1001. jq(".message_dialog_btn").removeClass("display-none");
  1002. if (smallChatHeight) {
  1003. $smallChatMainWindow.css("height", smallChatHeight);
  1004. }
  1005. if (!currentAccount) {
  1006. jq(".chat_contact_loader").removeClass("display-none");
  1007. }
  1008. if (currentStatus == OFFLINE) {
  1009. chooseUserStatus(ONLINE);
  1010. }
  1011. }
  1012. function closeChat() {
  1013. var smallChatHeight = sessionStorageManager.getItem("SmallChatHeight"),
  1014. $showSmallChatIcon = jq(".show_small_chat_icon"),
  1015. $smallChatMainWindow = jq(".small_chat_main_window"),
  1016. $notifications = jq(".notification_username"),
  1017. $noRemove = jq(".chat_contact_loader"),
  1018. $contactContainer = jq(".contact_container");
  1019. sessionStorageManager.setItem("WasConnected", false);
  1020. sessionStorageManager.setItem("WasLoad", false);
  1021. var dialogsNumber = sessionStorageManager.getItem("dialogsNumber"),
  1022. dialogsNumberInMenu = sessionStorageManager.getItem("dialogsNumberInMenu") || 0;
  1023. for (var i = 0; i < dialogsNumber; i++) {
  1024. sessionStorageManager.removeItem("userName" + i);
  1025. }
  1026. for (var i = 0; i < dialogsNumberInMenu; i++) {
  1027. sessionStorageManager.removeItem("dn_userName");
  1028. }
  1029. sessionStorageManager.setItem("dialogsNumber", 0);
  1030. sessionStorageManager.setItem("dialogsNumberInMenu", 0);
  1031. jq(".conversation_block").remove();
  1032. jq(".message_dialog_btn").remove();
  1033. jq(".detail_user_list").remove();
  1034. $contactContainer.empty();
  1035. $contactContainer.html($noRemove);
  1036. currentAccount = null;
  1037. if ($notifications.length) {
  1038. for (var i = 0; i < $notifications.length; i++) {
  1039. jq($notifications[i]).closest("li").remove();
  1040. }
  1041. }
  1042. if (smallChatHeight) {
  1043. $smallChatMainWindow.css("height", "initial");
  1044. }
  1045. $smallChatMainWindow.removeClass("small_chat_main_window_full");
  1046. $showSmallChatIcon.addClass("small_chat_icon_white");
  1047. $showSmallChatIcon.removeClass("small_chat_icon_green");
  1048. jq(".contact_container").addClass("display-none");
  1049. jq(".small_chat_top_panel").addClass("display-none");
  1050. jq(".icon_ch_size").addClass("display-none");
  1051. if (!isMobile) {
  1052. $smallChatMainWindow.resizable("disable").removeClass("ui-state-disabled");
  1053. }
  1054. //restore default state
  1055. changeStatus(NUMBER_ONLINE, true);
  1056. }
  1057. function hideChat() {
  1058. var smallChatHeight = sessionStorageManager.getItem("SmallChatHeight"),
  1059. $showSmallChatIcon = jq(".show_small_chat_icon"),
  1060. $smallChatMainWindow = jq(".small_chat_main_window");
  1061. if (smallChatHeight) {
  1062. $smallChatMainWindow.css("height", "initial");
  1063. }
  1064. $smallChatMainWindow.removeClass("small_chat_main_window_full");
  1065. $showSmallChatIcon.addClass("small_chat_icon_white");
  1066. $showSmallChatIcon.removeClass("small_chat_icon_green");
  1067. jq(".contact_container").addClass("display-none");
  1068. jq(".small_chat_top_panel").addClass("display-none");
  1069. jq(".icon_ch_size").addClass("display-none");
  1070. if (!isMobile) {
  1071. $smallChatMainWindow.resizable("disable").removeClass("ui-state-disabled");
  1072. }
  1073. jq(".conversation_block").addClass("display-none");
  1074. jq(".message_dialog_btn").addClass("display-none");
  1075. jq(".detail_user_list").remove();
  1076. //restore default state
  1077. changeStatus(NUMBER_ONLINE, true);
  1078. }
  1079. function showOrHideSmallChat() {
  1080. if (!sessionStorageManager.getItem("WasConnected") && currentStatus != OFFLINE) {
  1081. if (jq.connection.hub.state === jq.connection.connectionState.connected) {
  1082. connectionStart();
  1083. showChat();
  1084. }
  1085. } else {
  1086. connectionStop();
  1087. hideChat();
  1088. }
  1089. }
  1090. function openContacts() {
  1091. if (shouldOpenContacts) {
  1092. shouldOpenContacts = false;
  1093. var dialogsNumber = sessionStorageManager.getItem("dialogsNumber"),
  1094. dialogsNumberInMenu = sessionStorageManager.getItem("dialogsNumberInMenu") || 0,
  1095. allDialogsNumber = dialogsNumber + dialogsNumberInMenu,
  1096. userName;
  1097. for (var i = 0; i < dialogsNumber; i++) {
  1098. userName = sessionStorageManager.getItem("userName" + i);
  1099. if (userName == sessionStorageManager.getItem("TenantGuid")) {
  1100. ASC.Controls.JabberClient.openTenant(currentAccount.TenantName);
  1101. } else {
  1102. ASC.Controls.JabberClient.openContact(userName);
  1103. }
  1104. }
  1105. for (var i = dialogsNumber; i < allDialogsNumber; i++) {
  1106. userName = sessionStorageManager.getItem("dn_userName" + (i - dialogsNumber));
  1107. if (userName == sessionStorageManager.getItem("TenantGuid")) {
  1108. ASC.Controls.JabberClient.openTenant(currentAccount.TenantName);
  1109. } else {
  1110. ASC.Controls.JabberClient.openContact(userName);
  1111. }
  1112. }
  1113. }
  1114. }
  1115. function extendChat() {
  1116. if (!jabberTalkWindow || jabberTalkWindow.closed) {
  1117. jabberTalkWindow = ASC.Controls.JabberClient.open();
  1118. if (!sessionStorageManager.getItem("WasConnected") && currentStatus != OFFLINE) {
  1119. shouldOpenContacts = false;
  1120. } else {
  1121. shouldOpenContacts = true;
  1122. }
  1123. setTimeout(function () {
  1124. if (session

Large files files are truncated, but you can click here to view the full file