index.js 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700
  1. $(function(){
  2. "use strict";
  3. if(location.host != purl(__HOSTNAME__).attr('host')){
  4. location.href = __HOSTNAME__;
  5. }
  6. Pomo.domain = 'messages';
  7. Pomo.unescapeStrings = true;
  8. var _ = window._ = function(text){
  9. try{
  10. var t = Pomo.getText(text);
  11. return t.translation;
  12. }catch(e){
  13. return text;
  14. }
  15. },
  16. loadingHTML = '<div class="loading"><div class="ui-widget ui-state-default ui-corner-all loading-spinner"></div></div>',
  17. dialogs = $('#dialogs').children('div'),
  18. memos,
  19. news,
  20. templates = [],
  21. logout = function(){
  22. $.removeCookie('user',{
  23. path: '/'
  24. });
  25. $.removeCookie('key',{
  26. path: '/'
  27. });
  28. $.removeCookie('token',{
  29. path: '/'
  30. });
  31. $.removeCookie('PHPSESSID',{
  32. path: '/'
  33. });
  34. $.ajax(__HOSTNAME__+'site/api/',{
  35. data: {
  36. action: 'logout'
  37. },
  38. complete: function(){
  39. location.reload();
  40. },
  41. dataType: 'json'
  42. });
  43. },
  44. LANG = navigator.language,
  45. lang = Pomo.load(
  46. __HOSTNAME__+'site/api?action=lang',{
  47. format: 'po',
  48. mode: 'ajax'
  49. }
  50. ),
  51. lang_keys = (function(){
  52. var keys = [];
  53. $('body').find('*').contents().filter(function(){
  54. return this.nodeType === 3;
  55. }).each(function(){
  56. keys.push({
  57. node: this,
  58. key: this.nodeValue
  59. });
  60. });
  61. return keys;
  62. })(),
  63. has_key = function(node){
  64. for(var i in lang_keys){
  65. if(node === lang_keys[i].node){
  66. return true;
  67. }
  68. }
  69. return false;
  70. },
  71. get_key = function(node){
  72. for(var i in lang_keys){
  73. if(node === lang_keys[i].node){
  74. return lang_keys[i].key;
  75. }
  76. }
  77. return false;
  78. },
  79. translate = function(parent){
  80. $(parent).find('*').contents().filter(function(){
  81. return this.nodeType === 3;
  82. }).each(function(){
  83. if(!has_key(this)){
  84. lang_keys.push({
  85. node: this,
  86. key: this.nodeValue
  87. });
  88. }
  89. this.nodeValue = _(get_key(this));
  90. });
  91. $(parent).find('input[type=submit],input[type=button]').each(function(){
  92. if(this.tagName == 'INPUT' && this.type == 'submit'){
  93. if(!has_key(this)){
  94. lang_keys.push({
  95. node: this,
  96. key: this.value
  97. });
  98. }
  99. this.value = _(get_key(this));
  100. }
  101. });
  102. };
  103. lang.ready(function(){
  104. $('script[id^=template-]').each(function(){
  105. templates[this.id.substr(9)] = Handlebars.compile($(this).html());
  106. });
  107. Handlebars.registerHelper('html',function(body){
  108. return new Handlebars.SafeString(body.replace(/(\b(https?|ftps?|file|irc):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig,"<a class='link' href='$1'>$1</a>"));
  109. });
  110. $('form').submit(function(){
  111. var form = $(this),
  112. btn = form.children('input[type=submit]'),
  113. action = form.children('input[type=hidden][name=action]').val();
  114. $.ajax(__HOSTNAME__+'site/api/?'+form.serialize(),{
  115. success: function(d){
  116. if(d.log){
  117. console.log(d.log);
  118. }
  119. btn.removeAttr('disabled');
  120. if(d.code === 0){
  121. switch(action){
  122. case 'oper':
  123. form.find('input[name=password]').val('');
  124. alert(_('Oper updated'));
  125. break;
  126. default:
  127. location.reload();
  128. }
  129. }else{
  130. alert(d.message);
  131. }
  132. },
  133. error: function(xhr,msg,e){
  134. console.error(e);
  135. alert(_("Could not submit the form")+": "+msg);
  136. btn.removeAttr('disabled');
  137. },
  138. dataType: 'json'
  139. });
  140. btn.attr('disabled','disabled');
  141. return false;
  142. }).children('input[type=hidden][name=action]').removeAttr('disabled');
  143. $('#logout').click(logout);
  144. $('#newpass-button').click(function(){
  145. $('#newpass-diag').dialog('open');
  146. });
  147. $('#roles-button').click(function(){
  148. $('#roles-diag').dialog('open');
  149. });
  150. $('#rehash-servers').click(function(){
  151. $.ajax(__HOSTNAME__+'site/api/?action=rehash',{
  152. success: function(d){
  153. if(d.log){
  154. console.log(d.log);
  155. }
  156. alert(d.message);
  157. $('#rehash-servers').removeAttr('disabled');
  158. },
  159. error: function(xhr,msg,e){
  160. console.error(e);
  161. alert(_("Could not rehash the servers")+": "+msg);
  162. $('#rehash-servers').removeAttr('disabled');
  163. },
  164. dataType: 'json'
  165. });
  166. $(this).attr('disabled','disabled');
  167. return false;
  168. });
  169. $('#2-factor-disable').click(function(){
  170. var btn = $(this);
  171. $.ajax(__HOSTNAME__+'site/api/?action=2-factor-delete',{
  172. success: function(d){
  173. if(d.log){
  174. console.log(d.log);
  175. }
  176. alert(d.message);
  177. btn.removeAttr('disabled');
  178. location.reload();
  179. },
  180. error: function(xhr,msg,e){
  181. console.error(e);
  182. alert("Could not disable 2-factor: "+msg);
  183. btn.removeAttr('disabled');
  184. },
  185. dataType: 'json'
  186. });
  187. $(this).attr('disabled','disabled');
  188. return false;
  189. });
  190. $('#sync-pass').click(function(){
  191. var btn = $(this);
  192. $.ajax(__HOSTNAME__+'site/api/?action=sync-pass',{
  193. success: function(d){
  194. if(d.log){
  195. console.log(d.log);
  196. }
  197. alert(d.message);
  198. btn.removeAttr('disabled');
  199. },
  200. error: function(xhr,msg,e){
  201. console.error(e);
  202. alert(_("Could not synchronize your password")+": "+msg);
  203. btn.removeAttr('disabled');
  204. },
  205. dataType: 'json'
  206. });
  207. btn.attr('disabled','disabled');
  208. return false;
  209. });
  210. $('#sync-groups').click(function(){
  211. var btn = $(this);
  212. $.ajax(__HOSTNAME__+'site/api/?action=sync-groups',{
  213. success: function(d){
  214. if(d.log){
  215. console.log(d.log);
  216. }
  217. alert(d.message);
  218. btn.removeAttr('disabled');
  219. },
  220. error: function(xhr,msg,e){
  221. console.error(e);
  222. alert(_("Could not synchronize your groups")+": "+msg);
  223. btn.removeAttr('disabled');
  224. },
  225. dataType: 'json'
  226. });
  227. btn.attr('disabled','disabled');
  228. return false;
  229. });
  230. $('#persona-register').hover(function(){
  231. $(this).addClass('ui-state-hover');
  232. },function(){
  233. $(this).removeClass('ui-state-hover');
  234. }).click(function(){
  235. if(confirm(_("This is an admin only feature. Continue?"))){
  236. navigator.id.request({
  237. siteName: 'Omninet'
  238. });
  239. }
  240. });
  241. if(navigator.id){
  242. navigator.id.watch({
  243. loggedInUser: $.cookie('personaUser'),
  244. onlogin: function(assertion){
  245. $.ajax({
  246. type: 'post',
  247. url: __HOSTNAME__+'site/api/?action=persona-login',
  248. data: {
  249. assertion: assertion
  250. },
  251. success: function(d){
  252. if(d.code !== 0){
  253. if(d.message){
  254. console.log(d.message);
  255. alert(d.message);
  256. }
  257. }
  258. location.reload();
  259. },
  260. error: function(xhr,s,e){
  261. navigator.id.logout();
  262. alert(_("Login failure")+": " + e);
  263. }
  264. });
  265. },
  266. onlogout: function(){
  267. //$('#logout').click();
  268. }
  269. });
  270. }
  271. $('button[id^=persona-remove-]').each(function(){
  272. var id = this.id.substr(15),
  273. btn = $(this);
  274. btn.click(function(){
  275. $.ajax(__HOSTNAME__+'site/api/?action=persona-remove&id='+id,{
  276. success: function(d){
  277. if(d.log){
  278. console.log(d.log);
  279. }
  280. if(d.message){
  281. alert(d.message);
  282. }
  283. location.reload();
  284. },
  285. error: function(xhr,msg,e){
  286. console.error(e);
  287. alert(_("Could not remove persona address")+": "+msg);
  288. btn.removeAttr('disabled');
  289. },
  290. dataType: 'json'
  291. });
  292. btn.attr('disabled','disabled');
  293. return false;
  294. });
  295. });
  296. $('.server-opers,.server-owner,.server-children,.server-parent').click(function(){
  297. $(this).next().toggle();
  298. }).next().hide();
  299. $('.button,button,input[type=button],input[type=submit]').button();
  300. $('.tabs').tabs({
  301. activate: function(e,ui){
  302. var url = $.url(),
  303. params = url.data.param.query;
  304. params.tab = ui.newPanel.attr('id');
  305. History.pushState({},document.title,url.attr('path')+'?'+$.param(params)+url.attr('anchor'));
  306. },
  307. create: function(e,ui){
  308. $(window).trigger('statechange');
  309. },
  310. heightStyle: 'fill'
  311. }).addClass('transparent').each(function(){
  312. var tabs = $(this);
  313. tabs.parent().resize(function(){
  314. tabs.tabs('refresh');
  315. });
  316. });
  317. dialogs.dialog({
  318. modal: true,
  319. draggable: false,
  320. autoOpen: false,
  321. width: 500
  322. });
  323. $('.menu').menu();
  324. $(window).on('statechange',function(){
  325. var url = $.url(),
  326. tab = url.param('tab'),
  327. params = url.data.param.query,
  328. tabel = $('.tabs').children('ul').children('li').children('a[href="#'+tab+'"]');
  329. if(tab && tabel.length == 1){
  330. $('.tabs').tabs('option','active',tabel.parent().index());
  331. }else{
  332. var href = $('.tabs').children('ul').children('li').children('a');
  333. if(href.length > 0){
  334. href = href.get(0).href;
  335. }else{
  336. href = '';
  337. }
  338. params.tab = $.url(href).attr('fragment');
  339. History.pushState({},document.title,url.attr('path')+'?'+$.param(params)+url.attr('anchor'));
  340. }
  341. }).trigger('statechange').resize(function(){
  342. dialogs.each(function(){
  343. var d = $(this);
  344. if(d.dialog('isOpen')){
  345. d.dialog("option", "position", "center");
  346. }
  347. });
  348. var b = $('#user-menu-button');
  349. if(b.length > 0){
  350. $('#user-menu').offset({
  351. top: b.offset().top
  352. });
  353. }
  354. });
  355. $('#login-diag,#verify-diag').dialog('option',{
  356. closeOnEscape: false,
  357. close: function(){
  358. location.href = 'http://omnimaga.org';
  359. },
  360. position:{
  361. my: "center",
  362. at: "center",
  363. of: window
  364. }
  365. }).dialog('open');
  366. if(typeof $.cookie('user') != 'undefined'){
  367. $('#login').find('input[name=username]').val($.cookie('user'));
  368. }
  369. if(typeof $.cookie('type') != 'undefined'){
  370. $('#login').find('select[name=type]').val($.cookie('type'));
  371. }
  372. $('#verify-diag').dialog('option','close',logout);
  373. $('.accordion').accordion({
  374. collapsible: true,
  375. active: false,
  376. heightStyle: 'content'
  377. }).css('max-height','500px');
  378. $('.tree').treegrid({
  379. initialState: 'collapsed'
  380. });
  381. $('#user-menu-button').click(function(){
  382. $('#user-menu').show();
  383. });
  384. $('#user-menu').css({
  385. position: 'fixed',
  386. right: '0'
  387. }).hover(function(){},function(){
  388. $(this).hide();
  389. }).click(function(){
  390. $(this).hide();
  391. }).hide();
  392. if(!Modernizr.inputtypes.date){
  393. $('input[type=date]').datepicker({
  394. dateFormat: 'yy-mm-dd'
  395. });
  396. }
  397. if(!Modernizr.inputtypes.datetime){
  398. $('input[type=datetime]').datetimepicker({
  399. dateFormat: 'yy-mm-dd',
  400. timeFormat:'HH:mm:ssZ'
  401. });
  402. }
  403. if(!Modernizr.inputtypes.number){
  404. $('input[type=number]').spinner();
  405. }
  406. window.ServerPing = function(){
  407. console.log(_("Server Ping"));
  408. $.ajax(__HOSTNAME__+'site/api/?action=ping',{
  409. success: function(d){
  410. if(d.log){
  411. console.log(d.log);
  412. }
  413. if(d.message){
  414. alert(d.message);
  415. }
  416. if(d.code!==0){
  417. location.reload();
  418. }
  419. },
  420. error: function(xhr,msg,e){
  421. console.error(e);
  422. alert(_("Could not ping server")+": "+msg);
  423. location.reload();
  424. },
  425. dataType: 'json'
  426. });
  427. setTimeout(window.ServerPing,1000*60*5); // Every 5 minutes
  428. };
  429. window.FetchMemos = function(once){
  430. console.log(_("Fetching Memos"));
  431. $('#memos').prepend(loadingHTML);
  432. $.ajax(__HOSTNAME__+'site/api/?action=get-memos',{
  433. success: function(d){
  434. if(d.log){
  435. console.log(d.log);
  436. }
  437. if(d.message){
  438. alert(d.message);
  439. }
  440. if(d.code!==0){
  441. location.reload();
  442. }
  443. var i,
  444. m;
  445. if(d.memos){
  446. for(i in d.memos){
  447. m = d.memos[i];
  448. m.date = m.date.year+'-'+m.date.month+'-'+m.date.day+' '+m.date.time;
  449. d.memos[i] = m;
  450. }
  451. if(typeof memos != 'undefined' && !once && ($(d.memos).not(memos).length !== 0 || $(memos).not(d.memos).length !== 0)){
  452. alert('New memo');
  453. }
  454. memos = d.memos;
  455. }
  456. $('#memos').html(templates.memos(d)).find('button').button();
  457. translate('#memos');
  458. $('body').resize();
  459. },
  460. error: function(xhr,msg,e){
  461. console.error(e);
  462. alert(_("Could not contact server")+": "+msg);
  463. location.reload();
  464. },
  465. dataType: 'json'
  466. });
  467. if(!once){
  468. setTimeout(window.ServerPing,1000*60); // Every minute
  469. }
  470. };
  471. window.ReplyToMemo = function(from){
  472. $('#memo-diag').dialog('open').find('input[name=to]').val(from);
  473. $('#memo-diag').find('input[name=message]').select();
  474. };
  475. window.DeleteMemos = function(){
  476. window.DeleteMemo('all',function(){
  477. window.FetchMemos(true);
  478. });
  479. };
  480. window.DeleteMemo = function(id,callback){
  481. console.log(_("Deleting memo")+": "+id);
  482. $('#memos').prepend(loadingHTML);
  483. $.ajax(__HOSTNAME__+'site/api/?action=delete-memo&id='+id,{
  484. success: function(d){
  485. if(d.log){
  486. console.log(d.log);
  487. }
  488. if(d.message){
  489. alert(d.message);
  490. }
  491. if(d.code!==0){
  492. location.reload();
  493. }
  494. $('#memo-'+id).remove();
  495. if(typeof callback != 'undefined'){
  496. callback();
  497. }
  498. $('#memos>.loading').remove();
  499. },
  500. error: function(xhr,msg,e){
  501. console.error(e);
  502. alert(_("Could not ping server")+": "+msg);
  503. location.reload();
  504. },
  505. dataType: 'json'
  506. });
  507. };
  508. window.FetchNews = function(once){
  509. console.log(_("Fetching News"));
  510. $('#news').prepend(loadingHTML);
  511. $.ajax(__HOSTNAME__+'site/api/?action=get-news',{
  512. success: function(d){
  513. if(d.log){
  514. console.log(d.log);
  515. }
  516. if(d.message){
  517. alert(d.message);
  518. }
  519. if(d.code!==0){
  520. location.reload();
  521. }
  522. var i,
  523. n;
  524. if(d.news){
  525. d.news = d.news.reverse();
  526. for(i in d.news){
  527. n = d.news[i];
  528. n.date = n.date.year+'-'+n.date.month+'-'+n.date.day+' '+n.date.time;
  529. d.news[i] = n;
  530. }
  531. if(typeof news != 'undefined' && !once && ($(d.news).not(news).length !== 0 || $(news).not(d.news).length !== 0)){
  532. alert(_('New news item'));
  533. }
  534. news = d.news;
  535. }
  536. $('#news').html(templates.news(d)).find('button').button();
  537. translate('#news');
  538. $('body').resize();
  539. },
  540. error: function(xhr,msg,e){
  541. console.error(e);
  542. alert(_("Could not contact server")+": "+msg);
  543. location.reload();
  544. },
  545. dataType: 'json'
  546. });
  547. if(!once){
  548. setTimeout(window.ServerPing,1000*60); // Every minute
  549. }
  550. };
  551. window.FetchChannels = function(){
  552. console.log(_("Fetching Channels"));
  553. $('#channels').prepend(loadingHTML);
  554. $.ajax(__HOSTNAME__+'site/api/?action=get-channels',{
  555. success: function(d){
  556. if(d.log){
  557. console.log(d.log);
  558. }
  559. if(d.message){
  560. alert(d.message);
  561. }
  562. if(d.code!==0){
  563. location.reload();
  564. }
  565. var i,
  566. j,
  567. f,
  568. n,
  569. u,
  570. div = $('<div>');
  571. if(d.channels && d.flags){
  572. for(i in d.channels){
  573. n = d.channels[i];
  574. if(n.users){
  575. for(j in n.users){
  576. u = n.users[j];
  577. if(u.flags){
  578. for(f in u.flags){
  579. u.flags[f] = {
  580. flag: u.flags[f],
  581. name: d.flags[u.flags[f]]
  582. };
  583. }
  584. }
  585. }
  586. d.channels[i] = n;
  587. }
  588. }
  589. }
  590. div.append(templates.channels(d)).find('button').button();
  591. translate(div);
  592. div.find('.tree').treegrid({
  593. initialState: 'collapsed'
  594. });
  595. $('#channels').html(div.children());
  596. $('body').resize();
  597. },
  598. error: function(xhr,msg,e){
  599. console.error(e);
  600. alert(_("Could not contact server")+": "+msg);
  601. location.reload();
  602. },
  603. dataType: 'json'
  604. });
  605. };
  606. window.DeleteChannel = function(channel){
  607. if(confirm(_('Are you sure you want to delete channel')+' '+channel)){
  608. console.log(_("Deleting channel")+": "+channel);
  609. $('#channels').prepend(loadingHTML);
  610. $.ajax(__HOSTNAME__+'site/api/?action=delete-channel',{
  611. data: {
  612. channel: channel
  613. },
  614. success: function(d){
  615. if(d.log){
  616. console.log(d.log);
  617. }
  618. if(d.message){
  619. alert(d.message);
  620. }
  621. if(d.code!==0){
  622. location.reload();
  623. }
  624. $('[id=channel-'+channel+']').remove();
  625. if(typeof callback != 'undefined'){
  626. callback();
  627. }
  628. $('#channels>.loading').remove();
  629. },
  630. error: function(xhr,msg,e){
  631. console.error(e);
  632. alert(_("Could not ping server")+": "+msg);
  633. location.reload();
  634. },
  635. dataType: 'json'
  636. });
  637. }
  638. };
  639. window.RegisterChannel = function(channel){
  640. console.log(_("Registering channel")+": "+channel);
  641. $('#channels').prepend(loadingHTML);
  642. $.ajax(__HOSTNAME__+'site/api/?action=register-channel',{
  643. data: {
  644. channel: channel
  645. },
  646. success: function(d){
  647. if(d.log){
  648. console.log(d.log);
  649. }
  650. if(d.message){
  651. alert(d.message);
  652. }
  653. if(d.code!==0){
  654. location.reload();
  655. }
  656. window.FetchChannels(true);
  657. $('#channels>.loading').remove();
  658. },
  659. error: function(xhr,msg,e){
  660. console.error(e);
  661. alert(_("Could not ping server")+": "+msg);
  662. location.reload();
  663. },
  664. dataType: 'json'
  665. });
  666. };
  667. window.ModifyChannelAccess = function(channel,user,id){
  668. var d = $('#channel-flags-diag');
  669. if(typeof user != 'undefined'){
  670. d.find('input[name=user]').val(user);
  671. }else{
  672. d.find('input[name=user]').val('');
  673. }
  674. d.find('input[type=checkbox]').prop('checked',false);
  675. if(typeof id != 'undefined'){
  676. $('div[id=channel-'+channel+']>table').find('tr.treegrid-parent-'+id).each(function(){
  677. var flag = this.className.substr(9,1);
  678. d.find('input[name^=flags]').each(function(){
  679. if(this.name.substr(6,1) == flag){
  680. $(this).prop('checked',true);
  681. }
  682. });
  683. });
  684. }
  685. d.find('input[name=channel]').val(channel);
  686. d.dialog('open');
  687. };
  688. setInterval(function(){
  689. if(LANG != window.navigator.language){
  690. console.log(_('Language change detected'));
  691. location.reload();
  692. }
  693. },1000);
  694. if(typeof delayedload == 'function'){
  695. delayedload();
  696. }
  697. $('body').show();
  698. $('body').resize();
  699. });
  700. });