PageRenderTime 65ms CodeModel.GetById 35ms RepoModel.GetById 0ms app.codeStats 0ms

/theory/public/js/theory.js

http://github.com/ralfonso/theory
JavaScript | 693 lines | 567 code | 99 blank | 27 comment | 122 complexity | d1bbadd03406a28e0ddd531735ab53b2 MD5 | raw file
  1. function debug(v) {
  2. $('#debug:visible').html('<br />' + v);
  3. setTimeout("$('#debug:visible').html('')",6000);
  4. }
  5. function getStatus() {
  6. // this function is a mess
  7. if (window.sliding == true)
  8. return;
  9. window.statusloads++;
  10. // if this is enabled in the config, stop refreshing the main page after twenty minutes of not seeing the mouse cursor
  11. if (window.statusloads > 160)
  12. return;
  13. if (!(window.frames['frmplaylist']))
  14. return;
  15. debug('loading status (' + window.statusloads + ')');
  16. // load the status data from the server
  17. $.getJSON('./mpdcontrol/status',
  18. function(data) {
  19. // change the icon displayed on the controls
  20. if (data.status.state == 'play') {
  21. $('#imgPlay').attr('src','./img/pause.png');
  22. }
  23. else if (data.status.state == 'stop' || data.status.state == 'pause') {
  24. $('#imgPlay').attr('src','./img/play.png');
  25. }
  26. // check to see if the playlist was updated
  27. if ($('#playlistid').val() != data.status.playlist) {
  28. // don't refresh the playlist if the user just removed a track. wait until next time.
  29. if (window.trackremoved) {
  30. window.trackremoved = false;
  31. }
  32. else {
  33. $('#frmplaylist').attr('src','./playlist')
  34. }
  35. $('#playlistid').val(data.status.playlist);
  36. }
  37. if (data.status.time) {
  38. var time = data.status.time.split(':');
  39. var currentseconds = time[0];
  40. var totalseconds = time[1];
  41. }
  42. else if (data.track && data.track.time) {
  43. var currentseconds = 0;
  44. var totalseconds = data.track.time;
  45. }
  46. else {
  47. var currentseconds = 0;
  48. var totalseconds = 0;
  49. }
  50. window.ignorepositionslide = true;
  51. $('#position-slider').slider('moveTo',currentseconds);
  52. // did someone change the volume?!
  53. if ($('#vol').html() != data.status.volume) {
  54. window.ignorevolumeslide = true;
  55. $('#volume-slider').slider('moveTo',data.status.volume);
  56. }
  57. $('#vol').html(data.status.volume);
  58. $('#vol').show();
  59. // set the buttons' state
  60. (data.status.repeat == 1) ? $('#repeat').addClass('enabled') : $('#repeat').removeClass('enabled');
  61. (data.status.random == 1) ? $('#random').addClass('enabled') : $('#random').removeClass('enabled');
  62. var currenttime = formatTime(currentseconds);
  63. var totaltime = formatTime(totalseconds);
  64. $('#time').html(currenttime + ' / ' + totaltime);
  65. $('#time').show();
  66. if (data.track.artist && data.track.title)
  67. $(document).attr('title','theory :: ' + data.track.artist + ' - ' + data.track.title + ' [' + currenttime + ' / ' + totaltime + ']');
  68. /* FIXME this is a big mess. it handles track changing a little different than stream track
  69. and needs more consistency */
  70. if (data.status.state == 'play' || data.status.state == 'pause') {
  71. if (data.track.id != $('#currentid').val()) {
  72. // playing a new track or stream
  73. // recreate slider with new parameters (track length changed)
  74. $('#position-slider').slider("destroy");
  75. $('#position-slider').slider(
  76. {
  77. 'min' : 0,
  78. 'max' : totalseconds,
  79. 'startValue': currentseconds,
  80. 'start': function() {
  81. window.sliding = true;
  82. },
  83. 'change' : function(e,ui) {
  84. seek($('#currentid').val(),ui.value);
  85. window.sliding = false;
  86. },
  87. 'slide' : function(e,ui) {
  88. var possec = formatTime(ui.value);
  89. $('#time').html(possec + ' / ' + totaltime);
  90. }
  91. }
  92. );
  93. // set the current artist and title values to the hidden text boxes
  94. $('#currentartist').val(data.track.artist)
  95. $('#currenttitle').val(data.track.title);
  96. if (data.track.artist && data.track.title) {
  97. // we have a music file with good tags, update the appropriate stuff
  98. $('#title').html('');
  99. $('#title').append("<a style=\"cursor:pointer\" onclick=\"artistAlbums('" + data.track.artist.replace(/'/g,"\\'") + "')\">" + data.track.artist + "</a> - ");
  100. // if an album is set, make the track title clickable to take you to that album
  101. if (data.track.album)
  102. $('#title').append("<a style=\"cursor:pointer\" onclick=\"artistAlbums('" + data.track.artist.replace(/'/g,"\\'") + "','" + data.track.album.replace(/'/g,"\\'") + "')\">" + data.track.title + "</a>");
  103. else
  104. $('#title').append(data.track.title);
  105. }
  106. else if (data.track.file) {
  107. // this is for the playlist changing to a stream or a file without tags
  108. $('#currentartist').val('');
  109. $('#currenttitle').val('');
  110. $('#currentid').val('');
  111. $('#title').html(data.track.file);
  112. $('#wiki').hide();
  113. $('#currentart').attr('src','./img/50trans.gif');
  114. $('#currentartmask').attr('src','./img/50trans.gif');
  115. }
  116. $('#aWiki').attr('href','http://www.google.com/search?btnI=I\'m+Feeling+Lucky&q=site:en.wikipedia.org%20' + data.track.artist);
  117. $('#wiki').show();
  118. var arturl = './fetchart?artist=' + data.track.artist + '&album=' + data.track.album
  119. $('#currentartlink').attr('href',arturl)
  120. $('#currentart').attr('src',arturl)
  121. $('#currentartmask').attr('src','./img/albumart_mask.png');
  122. $('#currentartlink').lightBox();
  123. if (data.track.artist && data.track.title)
  124. $(document).attr('title','theory :: ' + data.track.artist + ' - ' + data.track.title + ' [' + currenttime + ' / ' + totaltime + ']');
  125. else if ($('#title').html() == 'not playing')
  126. $(document).attr('title','theory :: not playing');
  127. else
  128. $(document).attr('title','theory');
  129. if ($('#lyrics:visible').length)
  130. loadLyrics();
  131. }
  132. else if (data.track.name) {
  133. // current id didn't change, but update every time if we're playing a stream
  134. var title = data.track.name;
  135. var pagetitle = 'theory :: ' + data.track.name;
  136. if (data.track.title) {
  137. title += ' - ' + data.track.title;
  138. pagetitle += ' - ' + data.track.title;
  139. }
  140. $('#title').html(title);
  141. $(document).attr('title',pagetitle);
  142. }
  143. }
  144. else if (data.status.state == 'stop') {
  145. if (!data.track.file) {
  146. $(document).attr('title','theory :: not playing');
  147. $('#currentartist').val('');
  148. $('#currenttitle').val('');
  149. $('#currentid').val('');
  150. $('#title').html('not playing');
  151. $('#wiki').hide();
  152. $('#currentart').attr('src','./img/50trans.gif');
  153. $('#currentartmask').attr('src','./img/50trans.gif');
  154. }
  155. }
  156. if ($('#currentid').val() != data.track.id || $('#playlist li.selectedtrack',window.frames['frmplaylist'].document).length == 0) {
  157. $('#currentid').val(data.track.id);
  158. // this/ doesn't work on the initial page load because the frame isn't ready
  159. setPlaylistColors(window.frames['frmplaylist'].document,true);
  160. $('#playlist li[id^=track_' + data.track.id + ':]',window.frames['frmplaylist'].document).addClass('selectedtrack');
  161. }
  162. $('#currentid').val(data.track.id)
  163. }
  164. );
  165. }
  166. /* getPageSize() by quirksmode.com
  167. *
  168. * @return Array Return an array with page width, height and window width, height
  169. */
  170. function getPageSize() {
  171. var xScroll, yScroll;
  172. if (window.parent.innerHeight && window.parent.scrollMaxY) {
  173. xScroll = window.parent.innerWidth + window.parent.scrollMaxX;
  174. yScroll = window.parent.innerHeight + window.parent.scrollMaxY;
  175. } else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac
  176. xScroll = document.body.scrollWidth;
  177. yScroll = document.body.scrollHeight;
  178. } else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
  179. xScroll = document.body.offsetWidth;
  180. yScroll = document.body.offsetHeight;
  181. }
  182. var windowWidth, windowHeight;
  183. if (self.innerHeight) { // all except Explorer
  184. if(document.documentElement.clientWidth){
  185. windowWidth = window.parent.document.documentElement.clientWidth;
  186. } else {
  187. windowWidth = self.innerWidth;
  188. }
  189. windowHeight = self.innerHeight;
  190. } else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
  191. windowWidth = document.documentElement.clientWidth;
  192. windowHeight = document.documentElement.clientHeight;
  193. } else if (document.body) { // other Explorers
  194. windowWidth = document.body.clientWidth;
  195. windowHeight = document.body.clientHeight;
  196. }
  197. // for small pages with total height less then height of the viewport
  198. if(yScroll < windowHeight){
  199. pageHeight = windowHeight;
  200. } else {
  201. pageHeight = yScroll;
  202. }
  203. // for small pages with total width less then width of the viewport
  204. if(xScroll < windowWidth){
  205. pageWidth = xScroll;
  206. } else {
  207. pageWidth = windowWidth;
  208. }
  209. arrayPageSize = new Array(pageWidth,pageHeight,windowWidth,windowHeight);
  210. return arrayPageSize;
  211. }
  212. function jump(v) {
  213. window.frames['frmartists'].location.hash = 'jump' + v;
  214. }
  215. function setVolume(val) {
  216. // check to see if the slider was simply updated by status() if so, don't update MPD
  217. if (!window.ignorevolumeslide)
  218. $.get('./mpdcontrol/setvolume/' + val);
  219. window.ignorevolumeslide = false;
  220. }
  221. function seek(id,pos) {
  222. // check to see if the slider was simply updated by status() if so, don't update MPD
  223. if (!window.ignorepositionslide)
  224. $.get('./mpdcontrol/seek/' + id + '/' + pos);
  225. window.ignorepositionslide = false;
  226. }
  227. function formatTime(seconds)
  228. {
  229. var minutes = Math.floor(seconds / 60);
  230. var seconds = seconds - (minutes * 60);
  231. var retval = '';
  232. if (minutes >= 60) {
  233. hours = Math.floor(minutes / 60);
  234. minutes = minutes % 60;
  235. retval = hours + ":";
  236. }
  237. if (minutes < 10) {
  238. retval = retval + "0" + minutes + ":";
  239. }
  240. else {
  241. retval = retval + minutes + ":";
  242. }
  243. if (seconds < 10) {
  244. retval = retval + "0" + seconds;
  245. }
  246. else {
  247. retval = retval + seconds;
  248. }
  249. return retval;
  250. }
  251. function cmd(v) {
  252. $.get('./mpdcontrol/' + v);
  253. getStatus();
  254. }
  255. function artistAlbums(artist,album) {
  256. if (!album)
  257. album = '';
  258. window.parent.$('#frmalbums').attr('src','./albums?artist=' + encodeURIComponent(artist) + '&album=' + encodeURIComponent(album))
  259. window.parent.$('#frmtracks').attr('src','./tracks?artist=' + encodeURIComponent(artist) + '&album=' + encodeURIComponent(album))
  260. $('#list li:odd a',window.parent.frames['frmartists'].document).removeClass('activerow').addClass('oddrow');
  261. $('#list li:even a',window.parent.frames['frmartists'].document).removeClass('activerow').addClass('evenrow');
  262. $('#list li a:contains(' + artist + ')',window.parent.frames['frmartists'].document).each(
  263. function() {
  264. if ($(this).html() == artist)
  265. $(this).addClass('activerow');
  266. }
  267. );
  268. if (window.location.pathname != './artists') {
  269. if (artist.charCodeAt(0) < 65)
  270. jumpa = '#';
  271. else
  272. jumpa = artist.charAt(0).toLowerCase();
  273. window.parent.jump(jumpa);
  274. }
  275. }
  276. function albumTracks(artist,album) {
  277. window.parent.$('#frmtracks').attr('src','/tracks?artist=' + encodeURIComponent(artist) + '&album=' + encodeURIComponent(album))
  278. $('#list li:odd a',window.parent.frames['frmalbums'].document).removeClass('activerow').addClass('oddrow');
  279. $('#list li:even a',window.parent.frames['frmalbums'].document).removeClass('activerow').addClass('evenrow');
  280. $('#list li a:contains(' + album + ')',window.parent.frames['frmalbums'].document).each(
  281. function() {
  282. // wow this is a hack!
  283. if ($(this).html() == $('<div/>').text(album).html())
  284. $(this).addClass('activerow');
  285. }
  286. );
  287. }
  288. function resizeIframes() {
  289. if (window.innerHeight) {
  290. var theight = window.innerHeight - 357;
  291. var pheight = window.innerHeight - 145;
  292. var lheight = window.innerHeight - 200;
  293. var lwidth = window.innerWidth / 2 - 50;
  294. }
  295. else {
  296. var theight = document.documentElement.offsetHeight - 399 ;
  297. var pheight = document.documentElement.offsetHeight - 204;
  298. }
  299. $('#frmtracks').css('height',theight + 'px');
  300. $('#frmplaylist').css('height',pheight + 'px');
  301. $('#fakeborder',window.frames['frmplaylist'].document).height(pheight);
  302. $('#lyrics').css('height',lheight + 'px');
  303. $('#lyrics').css('width',lwidth + 'px');
  304. }
  305. function addToPlaylist(file) {
  306. var url = './mpdcontrol/addtoplaylist';
  307. $.ajax({
  308. url: url,
  309. type: 'POST',
  310. cache: false,
  311. data: 'file=' + file,
  312. success: function() {
  313. window.parent.$('#frmplaylist').attr('src','./playlist')
  314. }
  315. });
  316. }
  317. function removeTrack(el,id) {
  318. var url = './mpdcontrol/removetrack/' + id
  319. window.parent.trackremoved = true;
  320. $.ajax({
  321. url: url,
  322. type: 'GET',
  323. cache: false,
  324. success: function() {
  325. $(el).parent().remove();
  326. setPlaylistColors(document)
  327. if ($('#playlist li').length == 0) {
  328. empty_playlist_background();
  329. }
  330. }
  331. });
  332. }
  333. function removeMultipleTracks() {
  334. var url = './mpdcontrol/removemultipletracks/'
  335. var all_ids = Array();
  336. var iter = 0;
  337. alert($('ul#playlist li.selected'));
  338. $('ul#playlist li.selected').each(
  339. function() {
  340. var id = $(this).attr('id').split('_');
  341. all_ids[iter] = id
  342. id = id[1];
  343. id = id.split(':');
  344. id = id[0];
  345. url += id + ',';
  346. alert(id);
  347. iter += 1;
  348. });
  349. $.ajax({
  350. url: url,
  351. type: 'GET',
  352. cache: false,
  353. success: function() {
  354. for(i = 0; i < all_ids.length(); i++) {
  355. $('ul#playlist li#' + all_ids[i]).remove();
  356. }
  357. setPlaylistColors(document)
  358. if ($('#playlist li').length == 0) {
  359. empty_playlist_background();
  360. }
  361. }
  362. });
  363. }
  364. function setPlaylistColors(scope,force) {
  365. var addl = '';
  366. if (force != true)
  367. addl = ':not(li.selectedtrack)';
  368. $('#playlist li:even' + addl,scope).removeClass('selectedtrack').removeClass('evenrow').addClass('oddrow');
  369. $('#playlist li:odd' + addl,scope).removeClass('selectedtrack').removeClass('oddrow').addClass('evenrow');
  370. }
  371. function playNow(id) {
  372. var url = './mpdcontrol/playnow/' + id;
  373. $.ajax({
  374. url: url,
  375. type: 'GET',
  376. cache: false,
  377. success: function() {
  378. getStatus()
  379. }
  380. });
  381. }
  382. function addAlbum(artist,album) {
  383. var url = './mpdcontrol/addalbumtoplaylist?artist=' + encodeURIComponent(artist) + '&album=' + encodeURIComponent(album);
  384. $.ajax({
  385. url: url,
  386. type: 'GET',
  387. cache: false,
  388. success: function() {
  389. $('#frmplaylist').attr('src','./playlist')
  390. getStatus()
  391. }
  392. });
  393. }
  394. function addAllArtistAlbums(artist) {
  395. var url = './mpdcontrol/addartistalbums?artist=' + encodeURIComponent(artist);
  396. $.ajax({
  397. url: url,
  398. type: 'GET',
  399. cache: false,
  400. success: function() {
  401. $('#frmplaylist').attr('src','./playlist')
  402. getStatus()
  403. }
  404. });
  405. }
  406. function initConfig() {
  407. var arrPageSizes = getPageSize(); // from jquery-lightbox
  408. $('#dark-overlay').css({
  409. width: arrPageSizes[2],
  410. height: arrPageSizes[3]
  411. }).fadeIn();
  412. $('#config').show();
  413. }
  414. function hideConfig(reloadframes,reloadpage) {
  415. $('#config').hide();
  416. $('#dark-overlay').fadeOut();
  417. if (reloadpage) {
  418. document.location.replace('/');
  419. return;
  420. }
  421. if (reloadframes) {
  422. window.frames['frmartists'].location.reload();
  423. window.frames['frmplaylist'].location.reload();
  424. }
  425. getStatus();
  426. }
  427. function playlistAjax(func) {
  428. var url = './mpdcontrol/' + func;
  429. $.ajax({
  430. url: url,
  431. type: 'GET',
  432. cache: false,
  433. success: function() {
  434. window.location.reload()
  435. window.parent.getStatus();
  436. }
  437. });
  438. }
  439. function loadLyrics() {
  440. var artist = $('#currentartist').val()
  441. var track = $('#currenttitle').val()
  442. var url = '/lyrics?artist=' + artist + '&track=' + track;
  443. $('#lyrics').attr('src',url);
  444. $('#lyricsinfo').text(' (loading)')
  445. }
  446. function loadPlaylist() {
  447. var playlist = $('#playlists').val();
  448. if (playlist == '') {
  449. alert('please select a playlist to load')
  450. return;
  451. }
  452. var url = './playlist/load?name=' + playlist;
  453. $.ajax({
  454. url: url,
  455. type: 'GET',
  456. cache: false,
  457. success: function() {
  458. window.location.reload();
  459. window.parent.getStatus();
  460. }
  461. });
  462. }
  463. function deletePlaylist() {
  464. var playlist = $('#playlists').val();
  465. if (playlist == '') {
  466. alert('please select a playlist to delete')
  467. return;
  468. }
  469. if (!confirm('Are you sure you want to delete this playlist?'))
  470. return;
  471. var url = './playlist/delete?name=' + playlist;
  472. $.ajax({
  473. url: url,
  474. type: 'GET',
  475. cache: false,
  476. success: function() {
  477. $('#playlists option[value=' + playlist + ']').remove();
  478. }
  479. });
  480. }
  481. function fsStatus() {
  482. $.getJSON('./mpdcontrol/fs_status',
  483. function (data) {
  484. var begin_id = $('#currentid').html();
  485. if (data.current.title) {
  486. $('#not-playing').hide();
  487. $('#current').show();
  488. $('#next').show();
  489. $('#albumart-container').show();
  490. $('#progress').show();
  491. $('#currentid').html(data.current.id);
  492. $('#currenttrack').html(data.current.title);
  493. if (data.current.name) {
  494. $('#currentartist').html(data.current.name);
  495. $('#currentalbum').html();
  496. }
  497. else {
  498. $('#currentartist').html(data.current.artist);
  499. $('#currentalbum').html(data.current.album);
  500. }
  501. var arturl = './fetchart?artist=' + data.current.artist + '&album=' + data.current.album
  502. $('#albumart-container a').attr('href',arturl)
  503. $('#albumart').attr('src',arturl)
  504. $('#albumart-container a').lightBox();
  505. }
  506. else if (data.status.state == 'stop') {
  507. $('#currentid').html('')
  508. $('#current').hide();
  509. $('#next').hide();
  510. $('#albumart-container').hide();
  511. $('#progress').hide();
  512. $('#not-playing').show();
  513. $('#currenttrack').html(data.current.title);
  514. $('#currentartist').html(data.current.artist);
  515. $('#currentalbum').html(data.current.album);
  516. }
  517. if (data.status.time) {
  518. var time = data.status.time.split(':');
  519. var currentseconds = time[0];
  520. var totalseconds = time[1];
  521. }
  522. else if (data.track && data.track.time) {
  523. var currentseconds = 0;
  524. var totalseconds = data.track.time;
  525. }
  526. else {
  527. var currentseconds = 0;
  528. var totalseconds = 0;
  529. }
  530. var currenttime = formatTime(currentseconds);
  531. var totaltime = formatTime(totalseconds);
  532. if (time) {
  533. $('#playing-time').html(currenttime);
  534. $('#total-time').html(totaltime);
  535. var progress = currentseconds / totalseconds * 100;
  536. $('#progress-img').css('width',progress + '%');
  537. }
  538. if (begin_id != data.status.id)
  539. $('#next').html('');
  540. for (var i = 0; i < data.playlist.length; i++) {
  541. if (data.playlist[i].artist && data.playlist[i].title)
  542. var title = data.playlist[i].artist + ' - ' + data.playlist[i].title + '<br />';
  543. else
  544. var title = data.playlist[i].file + '<br />';
  545. $('#next').append(title);
  546. }
  547. });
  548. }
  549. function getURL() {
  550. var url = prompt('Please enter the URL of the stream you\'d like to append to the playlist:');
  551. if (url) {
  552. addToPlaylist(url);
  553. }
  554. }
  555. function editStream(name,url) {
  556. $('#oldname').val(name);
  557. $('#name').val(name);
  558. $('#url').val(url);
  559. $('#addtitle').html('edit stream');
  560. window.location.hash = 'form';
  561. }
  562. function playNext(id) {
  563. var url = './mpdcontrol/playnext/' + id;
  564. $.ajax({
  565. url: url,
  566. type: 'GET',
  567. cache: false,
  568. success: function() {
  569. window.location.reload()
  570. }
  571. });
  572. }
  573. function addPathToPlaylist(path) {
  574. var url = './mpdcontrol/addpathtoplaylist';
  575. $.ajax({
  576. url: url,
  577. type: 'POST',
  578. cache: false,
  579. data: 'path=' + path,
  580. success: function() {
  581. window.parent.$('#frmplaylist').attr('src','./playlist')
  582. }
  583. });
  584. }
  585. function setSearchType(s) {
  586. $('#searchtype').val(s);
  587. }
  588. function performSearch() {
  589. var q = $('#search input[name=q]').val();
  590. var searchtype = $('#searchtype').val()
  591. $('#searchresults').load('./search?searchtype=' + searchtype + '&q=' + q,undefined,function(){
  592. $('#searchresults').show('slide',{direction:'down'},1500);
  593. });
  594. }