main.js 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. const socket = io();
  2. $(() => {
  3. socket.on('serverHandshake', onServerHandshake);
  4. socket.on('serverLogin', onServerLogin);
  5. socket.on('serverKick', onServerKick);
  6. });
  7. function onServerHandshake() {
  8. resetChatListeners();
  9. resetLoginListeners();
  10. var template = $('#chat-login-template').html();
  11. $('#chat-host').empty();
  12. $('#chat-host').append(template);
  13. $('#chat-login-form').submit((e) => {
  14. e.preventDefault();
  15. socket.emit('login', $('#chat-login-form .username').val(), $('#chat-login-form .password').val());
  16. return false;
  17. });
  18. socket.on('usernameInvalid', () => {
  19. $('#chat-login-form .username').focus();
  20. $('#chat-host .loginError').text('Username invalid.');
  21. });
  22. socket.on('usernameTaken', () => {
  23. $('#chat-login-form .username').focus();
  24. $('#chat-host .loginError').text('Username already in use.');
  25. });
  26. socket.on('passwordRequired', () => {
  27. $('#chat-login-form .passwordWrapper').css('display', '');
  28. $('#chat-login-form .password').focus();
  29. $('#chat-host .loginError').text('Für diesen reservierten Benutzer ist ein Passwort erforderlich.');
  30. });
  31. socket.on('passwordWrong', () => {
  32. $('#chat-login-form .passwordWrapper').css('display', '');
  33. $('#chat-login-form .password').focus();
  34. $('#chat-host .loginError').text('Das eingegebene Passwort ist ungültig.');
  35. });
  36. }
  37. function onServerLogin(user, history) {
  38. resetChatListeners();
  39. resetLoginListeners();
  40. var template;
  41. if (user.admin) {
  42. template = $('#chat-admin-template').html()
  43. } else {
  44. template = $('#chat-template').html()
  45. }
  46. $('#chat-host').empty();
  47. $('#chat-host').append(template);
  48. $('#chat-host').append($('#chat-message-form-template').html());
  49. $('#chat-host .messageField').focus();
  50. for (const historyMsg of history) {
  51. appendUserMessage(historyMsg.msg, historyMsg.user, historyMsg.timestamp, user);
  52. }
  53. socket.on('usersUpdated', (userList) => {
  54. $('#chat-host .main .userlist').empty();
  55. userList.sort((userA, userB) => userA.name.localeCompare(userB.name));
  56. userList.sort((userA, userB) => {
  57. if (userA.admin && !userB.admin) {
  58. return Number.MIN_SAFE_INTEGER;
  59. } else if (!userA.admin && userB.admin) {
  60. return Number.MAX_SAFE_INTEGER;
  61. }
  62. return 0;
  63. });
  64. for (let listUser of userList) {
  65. let userString = listUser.name;
  66. if (listUser.admin) {
  67. userString = '👑 ' + userString;
  68. }
  69. const userListEl = $('<li>');
  70. const usernameEl = $('<span>');
  71. usernameEl.text(userString);
  72. usernameEl.css('color', listUser.color);
  73. userListEl.append(usernameEl);
  74. if (user.admin) {
  75. const kickBtn = $('<button class="kickBtn">🥾</button>');
  76. kickBtn.click(() => onKickUser(listUser));
  77. userListEl.append(kickBtn);
  78. }
  79. $('#chat-host .main .userlist').append(userListEl);
  80. }
  81. });
  82. if (user.admin) {
  83. socket.on('bannedUpdated', (bannedList) => {
  84. $('#chat-host .main .bannedlist').empty();
  85. for (let bannedItem of bannedList) {
  86. const bannedListEl = $('<li>');
  87. bannedListEl.text(bannedItem.ip + ' (' + bannedItem.user.name + ')');
  88. const removeBtn = $('<button class="removeBtn">✖</button>');
  89. removeBtn.click(() => onLiftBan(bannedItem.ip));
  90. bannedListEl.append(removeBtn);
  91. $('#chat-host .main .bannedlist').append(bannedListEl);
  92. }
  93. });
  94. }
  95. socket.on('message', (msg, msgUser, timestamp) => appendUserMessage(msg, msgUser, timestamp, user));
  96. socket.on('userJoined', (msg) => {
  97. appendMessage($('<li class="systemMsg user joined">').text(msg + ' hat den Chat betreten.'));
  98. });
  99. socket.on('userLeft', (msg) => {
  100. appendMessage($('<li class="systemMsg user left">').text(msg + ' hat den Chat verlassen.'));
  101. });
  102. $('#chat-host .messageForm').submit((e) => {
  103. e.preventDefault();
  104. socket.emit('message', $('#chat-host .messageForm .messageField').val());
  105. $('#chat-host .messageForm .messageField').val('');
  106. $('#chat-host .messageForm .messageField').focus();
  107. return false;
  108. });
  109. $("#chat-host .messageField").keypress((e) => {
  110. if(e.key == 'Enter' && !e.shiftKey) {
  111. e.preventDefault();
  112. $('#chat-host .messageForm').submit();
  113. return false;
  114. }
  115. });
  116. }
  117. function onServerKick() {
  118. resetChatListeners();
  119. resetLoginListeners();
  120. var template = $('#chat-kick-template').html();
  121. $('#chat-host').empty();
  122. $('#chat-host').append(template);
  123. }
  124. function resetChatListeners() {
  125. socket.removeAllListeners('usersUpdated');
  126. socket.removeAllListeners('message');
  127. socket.removeAllListeners('userJoined');
  128. socket.removeAllListeners('userLeft');
  129. }
  130. function resetLoginListeners() {
  131. socket.removeAllListeners('usernameInvalid');
  132. socket.removeAllListeners('usernameTaken');
  133. socket.removeAllListeners('passwordRequired');
  134. socket.removeAllListeners('passwordWrong');
  135. }
  136. function appendMessage(element) {
  137. const messagesListEl = $('#chat-host .main .messages')[0];
  138. const scrollMax = messagesListEl.scrollHeight - messagesListEl.clientHeight;
  139. const scrolled = messagesListEl.scrollTop != scrollMax;
  140. $('#chat-host .main .messages').append(element);
  141. // TODO: Scrolling
  142. //if (!scrolled) {
  143. messagesListEl.scrollTop = messagesListEl.scrollHeight - messagesListEl.clientHeight;
  144. //}
  145. }
  146. function appendUserMessage(msg, msgUser, timestamp, user) {
  147. const messageWrapper = $('<li class="userMsg">');
  148. if(user.name == msgUser.name) {
  149. messageWrapper.addClass('self');
  150. }
  151. messageWrapper.css('borderColor', msgUser.color);
  152. const avaEl = $('<img class="avatar" />');
  153. avaEl.prop('src', '/img/ava/' + msgUser.name);
  154. avaEl.css('backgroundColor', msgUser.color);
  155. messageWrapper.append(avaEl);
  156. const timeEl = $('<span class="time">');
  157. timeEl.text(new Date(timestamp).toLocaleTimeString());
  158. timeEl.prop('title', new Date(timestamp).toLocaleString());
  159. messageWrapper.append(timeEl);
  160. const userEl = $('<span class="user">');
  161. let userString = msgUser.name;
  162. if (msgUser.admin) {
  163. userString = '👑 ' + userString;
  164. }
  165. userEl.text(userString);
  166. userEl.css('color', msgUser.color);
  167. messageWrapper.append(userEl);
  168. const messageEl = $('<span class="message">');
  169. messageEl.html(msg)
  170. messageWrapper.append(messageEl);
  171. appendMessage(messageWrapper);
  172. }
  173. function onKickUser(user) {
  174. if (confirm('Möchten Sie den Benutzer "' + user.name + '" wirklich bannen?\nDies wird sich auf alle Benutzer mit der gleichen IP-Adresse auswirken.')) {
  175. socket.emit('requestKick', user);
  176. }
  177. }
  178. function onLiftBan(ip) {
  179. socket.emit('requestLiftBan', ip);
  180. }