app.js 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. /*
  2. Copyright (c) 2019 Farooq Karimi Zadeh <fkz@riseup.net>
  3. VM-IRC is under GNU LGPL 3 or at your option any later version and comes
  4. without any warranty from author(s).
  5. */
  6. var nick_ = null, channel = null, sock = null, firsttime = true;
  7. var quit = false;
  8. var UTF8 = {
  9. encode: function(s){
  10. return unescape(encodeURIComponent(s));
  11. },
  12. decode: function(s){
  13. return decodeURIComponent(escape(s));
  14. }
  15. };
  16. document.onkeydown = function (e) {
  17. switch (e.key) {
  18. case "Enter":
  19. if (sock == null || sock.readyState != "open"){
  20. alert("socket not ready!");
  21. break;
  22. }
  23. var msg_text = prompt("Message to channel");
  24. if (msg_text == null)
  25. break;
  26. var msg_to_add = "<span style=\"color: gray\">" + "&lt;" + nick_ +
  27. "&gt; " + msg_text + "<br>" + "</span>";
  28. document.getElementById("messages").innerHTML += msg_to_add;
  29. msg_text = UTF8.encode(msg_text);
  30. sock.send("PRIVMSG " + channel + " :" + msg_text + "\r\n");
  31. window.scrollByLines(3);
  32. break;
  33. case "SoftRight":
  34. if (sock != null && sock.readyState == "open"){
  35. quit = true;
  36. sock.send("QUIT\r\n");
  37. sock.close();
  38. }
  39. window.close();
  40. break;
  41. case "SoftLeft":
  42. var towhom = prompt("To whom?");
  43. if (towhom == null)
  44. break;
  45. var msg_text = prompt("Message to " + towhom);
  46. if (msg_text == null)
  47. break;
  48. document.getElementById("messages").innerHTML += "&gt;" + nick_
  49. + "&lt; " +msg_text+ "<br>";
  50. msg_text = UTF8.encode(msg_text);
  51. sock.send("PRIVMSG " + towhom + " :" + msg_text + "\r\n");
  52. break;
  53. case "1":
  54. var current_size = Number(document.body.style.fontSize.replace("px", ""));
  55. if (current_size === 0) break;
  56. current_size--;
  57. document.body.style.fontSize = current_size.toString() + "px";
  58. break;
  59. case "2":
  60. document.body.style.fontSize = "12px";
  61. break;
  62. case "3":
  63. var current_size = Number(document.body.style.fontSize.replace("px", ""));
  64. if (current_size === "64") break;
  65. current_size++;
  66. document.body.style.fontSize = current_size.toString() + "px";
  67. break;
  68. }
  69. }
  70. window.onload = function (e) {
  71. var def;
  72. document.body.style.fontSize = "12px";
  73. if (nick_ === null){
  74. def = window.localStorage.getItem("nick");
  75. if (def === null){
  76. nick_ = prompt("Nick (max 9 chars)");
  77. }else{
  78. nick_ = prompt("Nick (max 9 chars) or press OK for " + def);
  79. if (nick_ === ""){
  80. nick_ = def;
  81. }
  82. }
  83. window.localStorage.setItem("nick", nick_);
  84. }
  85. if (nick_ === null) window.close();
  86. if (channel === null){
  87. def = window.localStorage.getItem("channel");
  88. if (def === null){
  89. channel = prompt("Channel(just one!)", def);
  90. }else{
  91. channel = prompt("Channel(just one!) or press OK for " + def);
  92. if (channel === ""){
  93. channel = def;
  94. }
  95. }
  96. window.localStorage.setItem("channel", channel);
  97. }
  98. if (channel === null) window.close();
  99. if (!channel.startsWith("#"))
  100. channel = "#" + channel;
  101. sock = navigator.mozTCPSocket.open("irc.freenode.net",6697,{useSecureTransport: true});
  102. sock.onopen = function (e) {
  103. e.target.send("USER vm-irc vm-irc vm-irc :VM-IRC User\r\n");
  104. e.target.send("NICK " + nick_ + "\r\n");
  105. e.target.send("JOIN " + channel + "\r\n");
  106. }
  107. sock.ondata = function (e) {
  108. if (!(typeof(e.data) === "string"))
  109. return;
  110. var msgs = e.data.split("\r\n");
  111. for (let msg of msgs){
  112. if (msg.startsWith("PING")){
  113. e.currentTarget.send("PONG " + msg.split(" ")[1] + "\r\n");
  114. }
  115. msg = UTF8.decode(msg);
  116. var token = msg.split(" ", 3);
  117. var nick = token[0].split("!")[0].replace(":", "");
  118. if (token[1] === "PRIVMSG"){
  119. var target = token[2];
  120. var msg_text = msg.slice(msg.search(" :") + 2, msg.length);
  121. if (target === channel){
  122. nick = "&lt;" + nick + "&gt;";
  123. }else if (target === nick_){
  124. nick = "&gt;" + nick + "&lt;";
  125. }
  126. var text = nick + " " + msg_text + "<br>";
  127. if (msg_text.search(nick_) != -1 || target === nick_)
  128. text = "<b>" + text + "<b>";
  129. if (document.visibilityState === "hidden"){
  130. if (window.Notification.permission === "granted"){
  131. var vibrate_pattern = [200, 100, 200, 100, 200];
  132. new window.Notification(nick, {body: msg_text,
  133. vibrate:vibrate_pattern
  134. });
  135. }
  136. }
  137. document.getElementById("messages").innerHTML += text;
  138. window.scrollByLines(3);
  139. }
  140. if (token[1] === "NOTICE"){
  141. var msg_text = msg.slice(msg.search(" :") + 2, msg.length);
  142. var text = "-" + nick + "- " + msg_text + "<br>";
  143. document.getElementById("messages").innerHTML += text;
  144. window.scrollByLines(3);
  145. }
  146. if (token[1] === "JOIN"){
  147. document.getElementById("messages").innerHTML += nick + " joined.<br>";
  148. window.scrollByLines(1);
  149. }
  150. if (token[1] === "PART"){
  151. document.getElementById("messages").innerHTML += nick + " left.<br>";
  152. window.scrollByLines(1);
  153. }
  154. if (token[1] === "QUIT"){
  155. document.getElementById("messages").innerHTML += nick + " has quit.<br>";
  156. window.scrollByLines(1);
  157. }
  158. if (token[1] === "353"){ // Channel user list
  159. let nicks = msg.replace(/:/g, "").split(" ").slice(5).join(" ");
  160. if (firsttime)
  161. document.getElementById("messages").innerHTML += "Users: ";
  162. document.getElementById("messages").innerHTML += nicks + " ";
  163. }
  164. if (token[1] === "366"){
  165. document.getElementById("messages").innerHTML += "<br>";
  166. firsttime = true;
  167. }
  168. if (token[1] === "332"){ // Reply to TOPIC command
  169. let topic = msg.slice(msg.replace(":", ".").search(":") + 1, msg.length);
  170. document.getElementById("messages").innerHTML += "Topic: " +
  171. topic + "<br>";
  172. }
  173. if (token[1] === "433"){ // Nick name already in use
  174. nick_ += "_";
  175. e.currentTarget.send("NICK " + nick_ + "\r\n");
  176. }
  177. if (token[1] === "NICK"){
  178. if (nick === nick_)
  179. nick_ = token[2].replace(":", "");
  180. else
  181. document.getElementById("messages").innerHTML += nick + " changed their nick to " + token[2].replace(":", "") + "<br>";
  182. }
  183. }
  184. }
  185. sock.onclose = function (e) {
  186. if (!quit){
  187. window.onload({});
  188. }
  189. }
  190. }