omnomirc.js 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431
  1. /*
  2. OmnomIRC COPYRIGHT 2010,2011 Netham45
  3. OmnomIRC3 rewrite COPYRIGHT 2013 Nathaniel 'Eeems' van Diepen
  4. This file is part of OmnomIRC.
  5. OmnomIRC is free software: you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation, either version 3 of the License, or
  8. (at your option) any later version.
  9. OmnomIRC is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with OmnomIRC. If not, see <http://www.gnu.org/licenses/>.
  15. */
  16. (function(window,$,io,undefined){
  17. var $o = window.OmnomIRC = window.$o = function(){
  18. return 'Version: '+$o.version
  19. },
  20. event = function(msg,type){
  21. type=typeof type == 'undefined'?'event':type;
  22. switch(type){
  23. case 'ready':type='document_ready';break;
  24. }
  25. log('['+type.toUpperCase()+'] '+msg);
  26. },
  27. log = function(){
  28. console.log.apply(console,arguments);
  29. },
  30. exists = function(object){
  31. return typeof object != 'undefined';
  32. },
  33. prevent = function(e){
  34. e.stopImmediatePropagation();
  35. e.stopPropagation();
  36. e.preventDefault();
  37. return false;
  38. },
  39. selectedTab=0,
  40. settings = {
  41. colour: false
  42. },
  43. tabs = [],
  44. properties = {
  45. nick: 'User',
  46. sig: '',
  47. tabs: tabs,
  48. server: location.origin,
  49. autojoin: [
  50. '#omnimaga',
  51. '#irp'
  52. ]
  53. },
  54. commands = [
  55. {
  56. cmd: 'help',
  57. fn: function(args){
  58. var m = 'Commands:',i;
  59. for(i in commands){
  60. m += ' '+commands[i].cmd;
  61. }
  62. $o.msg(m);
  63. }
  64. },
  65. {
  66. cmd: 'open',
  67. fn: function(args){
  68. tabs.push({
  69. name: args[1],
  70. title: args[2],
  71. topic: 'Topic for '+args[2]
  72. });
  73. $o.refreshTabs();
  74. }
  75. },
  76. {
  77. cmd: 'clear',
  78. fn: function(args){
  79. $cl.html('');
  80. }
  81. },
  82. {
  83. cmd: 'close',
  84. fn: function(args){
  85. if(args.length > 1){
  86. $o.removeTab(args[1]);
  87. }else{
  88. $o.removeTab(selectedTab);
  89. }
  90. }
  91. },
  92. {
  93. cmd: 'tabs',
  94. fn: function(args){
  95. $o.msg('tabs:');
  96. for(var i in tabs){
  97. $o.msg(' ['+i+'] '+tabs[i].name);
  98. }
  99. }
  100. }
  101. ],
  102. handles = [
  103. {
  104. on: 'connect',
  105. fn: function(){
  106. for(var i in settings.autojoin){
  107. socket.emit('join',{name: settings.autojoin[i]});
  108. }
  109. }
  110. },
  111. {
  112. on: 'join',
  113. fn: function(data){
  114. $o.addTab(data.name,data.title);
  115. }
  116. }
  117. ],
  118. socket,$i,$s,$h,$cl,$tl,hht;
  119. $.extend($o,{
  120. version: '3.0',
  121. connect: function(server){
  122. if($o.connected()){
  123. socket.disconnect();
  124. }
  125. if(typeof server == 'undefined'){
  126. server = settings.server;
  127. }
  128. socket = io.connect(server);
  129. for(var i in handles){
  130. socket.on(handles[i].on,handles[i].fn);
  131. }
  132. },
  133. connected: function(){
  134. return typeof socket != 'undefined';
  135. },
  136. get: function(name){
  137. return exists(settings[name])?settings[name]:false;
  138. },
  139. set: function(name,value){
  140. if(exists(settings[name])){
  141. settings[name] = value;
  142. $.localStorage('settings',$.stringify(settings));
  143. return true;
  144. }else{
  145. return false;
  146. }
  147. },
  148. prop: function(name){
  149. return exists(properties[name])?properties[name]:null;
  150. },
  151. send: function(msg){
  152. if(msg !== ''){
  153. if(msg[0] == '/'){
  154. var args = msg.split(' '),
  155. cmd = args[0].substr(1),
  156. i;
  157. event(msg,'command');
  158. for(i in commands){
  159. if(commands[i].cmd == cmd){
  160. commands[i].fn(args);
  161. return;
  162. }
  163. }
  164. $o.msg(cmd+' is not a valid command.');
  165. }else{
  166. event(msg,'send');
  167. $o.msg({
  168. text: msg,
  169. user: properties.nick
  170. });
  171. }
  172. }
  173. },
  174. msg: function(msg){
  175. switch(typeof msg){
  176. case 'string':
  177. $cl.append($('<li>').html(msg.htmlentities()));
  178. break;
  179. case 'object':
  180. $cl.append($('<li>').html('&lt;'+msg.user+'&gt;&nbsp;'+msg.text.htmlentities()));
  181. break;
  182. }
  183. },
  184. event: function(event_name,message){
  185. event(message,event_name);
  186. },
  187. selectTab: function(id){
  188. event(id,'tab_select');
  189. if(id<tabs.length-1&&id>=0){
  190. selectedTab=id;
  191. }
  192. $tl.children('.clicked').removeClass('clicked');
  193. $($tl.children().get(id)).addClass('clicked');
  194. $('#title').text(tabs[id].title);
  195. $('#topic').text(tabs[id].topic);
  196. },
  197. tabDOM: function(id){
  198. },
  199. addTab: function(name,title){
  200. event('Tab added: '+name);
  201. tabs.push({
  202. name: name,
  203. title: title
  204. });
  205. $tl.append($o.tabObj(tabs.length-1));
  206. },
  207. removeTab: function(id){
  208. if(typeof tabs[id] != 'undefined'){
  209. event('Tab removed: '+tabs[id].name);
  210. tabs.splice(id,1);
  211. if(selectedTab==id&&selectedTab>0){
  212. selectedTab--;
  213. }
  214. }
  215. $o.refreshTabs();
  216. },
  217. tabObj: function(id){
  218. if(typeof id !== 'undefined'){
  219. return $('<div>')
  220. .addClass('tab')
  221. .text(tabs[id].title)
  222. .mouseup(function(e){
  223. switch(e.which){
  224. case 1: // RMB
  225. if($(this).data('id')!=selectedTab){
  226. $o.selectTab($(this).data('id'));
  227. return prevent(e);
  228. }
  229. break;
  230. case 2: // MMB
  231. $(this).children('span.close-button').click();
  232. return prevent(e);
  233. break;
  234. case 3: // LMB
  235. return prevent(e);
  236. break;
  237. default:
  238. return prevent(e);
  239. }
  240. })
  241. .append(
  242. $('<span>')
  243. .addClass('close-button')
  244. .click(function(){
  245. $o.removeTab(id);
  246. return false;
  247. })
  248. .css({
  249. 'position': 'absolute',
  250. 'background-color': 'inherit',
  251. 'top': 0,
  252. 'right': 0
  253. })
  254. .html('&times;')
  255. )
  256. .data('id',id);
  257. }
  258. },
  259. refreshTabs: function(){
  260. $tl.html('');
  261. var i,tab;
  262. for(i in tabs){
  263. tab = $o.tabObj(i);
  264. if(i==selectedTab){
  265. tab.addClass('clicked');
  266. $('#title').text(tabs[i].title);
  267. $('#topic').text(tabs[i].topic);
  268. }
  269. $tl.append(tab);
  270. }
  271. if($tl.get(0).scrollHeight-20 != $tl.scrollTop()){
  272. $('#tabs-scroll-right').removeClass('disabled');
  273. }
  274. if($tl.scrollTop() != 0){
  275. $('#tabs-scroll-left').removeClass('disabled');
  276. }
  277. }
  278. });
  279. String.prototype.htmlentities = function(){
  280. return this.replace(/&/g, '&amp;').replace(/\s/g, '&nbsp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
  281. };
  282. $(document).ready(function(){
  283. $.extend(settings,$.parseJSON($.localStorage('settings')));
  284. $.localStorage('settings',$.stringify(settings));
  285. $i = $('#input');
  286. $s = $('#send');
  287. $cl = $('#content-list');
  288. $tl = $('#tabs-list');
  289. $h = $('#head');
  290. $s.click(function(){
  291. if(!$s.hasClass('clicked')){
  292. $s.addClass('clicked');
  293. setTimeout(function(){
  294. $s.removeClass('clicked');
  295. },500);
  296. }
  297. $o.send($i.val());
  298. $i.val('');
  299. });
  300. $i.keypress(function(e){
  301. if(e.keyCode == 13){
  302. if(!$s.hasClass('clicked')){
  303. $s.addClass('clicked');
  304. setTimeout(function(){
  305. $s.removeClass('clicked');
  306. },500);
  307. }
  308. $o.send($i.val());
  309. $i.val('');
  310. }
  311. });
  312. $('#settings, #users').click(function(){
  313. $(this).addClass('open');
  314. $(this).children('.close-button').show();
  315. }).hover(function(){
  316. $(this).addClass('hovered');
  317. },function(){
  318. $(this).removeClass('hovered');
  319. }).children('.close-button').click(function(){
  320. $(this).parent().removeClass('open');
  321. $(this).hide();
  322. return false;
  323. }).hide();
  324. $('#users').hoverIntent({
  325. out: function(){
  326. $(this).removeClass('open');
  327. $(this).children('.close-button').hide();
  328. },
  329. timeout: 1000
  330. });
  331. $('#content').click(function(){
  332. $('#settings, #users, #head').removeClass('hovered').removeClass('open');
  333. $('#settings, #users').children('.close-button').hide()
  334. });
  335. $('.unselectable').attr('unselectable','on');
  336. $.contextMenu({
  337. selector: 'div.tab',
  338. items: {
  339. add: {
  340. name: 'New Tab',
  341. icon: 'add',
  342. callback: function(){
  343. $(this).contextMenu('hide');
  344. var title = prompt('Title');
  345. tabs.push({
  346. name: prompt('channel'),
  347. title: title,
  348. topic: 'Topic for '+title
  349. });
  350. $o.refreshTabs();
  351. }
  352. },
  353. s1: '',
  354. close: {
  355. name: 'Close',
  356. icon: 'delete',
  357. callback: function(){
  358. $(this).contextMenu('hide');
  359. $o.removeTab($(this).data('id'));
  360. }
  361. }
  362. },
  363. zIndex: 99999,
  364. trigger: 'right'
  365. });
  366. $.contextMenu({
  367. selector: '#tabs-list',
  368. items: {
  369. add: {
  370. name: 'New Tab',
  371. icon: 'add',
  372. callback: function(){
  373. $(this).contextMenu('hide');
  374. var title = prompt('Title');
  375. tabs.push({
  376. name: prompt('channel'),
  377. title: title,
  378. topic: 'Topic for '+title
  379. });
  380. $o.refreshTabs();
  381. }
  382. }
  383. },
  384. zIndex: 99999,
  385. trigger: 'right'
  386. });
  387. $('#tabs-scroll-right').click(function(){
  388. event('scroll right');
  389. $tl.scrollTop(($tl.scrollTop()||0)+20);
  390. if($tl.get(0).scrollHeight-20 == $tl.scrollTop()){
  391. $('#tabs-scroll-right').addClass('disabled');
  392. }
  393. $('#tabs-scroll-left').removeClass('disabled');
  394. });
  395. $('#tabs-scroll-left').click(function(){
  396. event('scroll left');
  397. $tl.scrollTop(($tl.scrollTop()||0)-20);
  398. if($tl.scrollTop() == 0){
  399. $('#tabs-scroll-left').addClass('disabled');
  400. }
  401. $('#tabs-scroll-right').removeClass('disabled');
  402. });
  403. (function scrollup(){
  404. $('#tabs-scroll-left').click();
  405. if($tl.scrollTop() != 0){
  406. setTimeout(scrollup,10);
  407. }
  408. })();
  409. //DEBUG
  410. /* for(var i=0;i<20;i++){
  411. tabs.push({
  412. name: '#Tab'+i,
  413. title: 'Tab '+i,
  414. topic: 'Topic for tab '+i
  415. });
  416. } */
  417. //END DEBUG
  418. $o.refreshTabs();
  419. event('Date '+new Date,'ready');
  420. $h.addClass('hovered');
  421. setTimeout(function(){
  422. $h.removeClass('hovered');
  423. },1000);
  424. $o.connect();
  425. });
  426. })(window,jQuery,io);