scripts/ajax.js
changeset 78 08f8a72b1f7b
parent 39 38dbcda3cf20
equal deleted inserted replaced
77:e5f1f45ea7e2 78:08f8a72b1f7b
    10  * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
    10  * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
    11  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
    11  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
    12  */
    12  */
    13 
    13 
    14 var ajax;
    14 var ajax;
    15 var is_playing = false, current_track = -1, current_track_length, current_track_pos, ct_advance_timeout = false, ct_counter = false, playlist_md5 = false, first_load = true;
    15 var is_playing = false, current_track = -1, current_track_length, current_track_pos, ct_advance_timeout = false, ct_counter = false, playlist_md5 = false, first_load = true, offline_mode = false;
    16 
    16 
    17 var onload_hooks = new Array();
    17 var onload_hooks = new Array();
    18 
    18 
    19 function addOnloadHook(func)
    19 function addOnloadHook(func)
    20 {
    20 {
    45       _f(e);
    45       _f(e);
    46     }
    46     }
    47   }
    47   }
    48 }
    48 }
    49 
    49 
       
    50 // preload "offline mode" large icon
       
    51 var preload = ['/offlinemodelarge.png', 'trans80.png']
       
    52 for ( var i = 0; i < preload.length; i++ )
       
    53 {
       
    54   var img = new Image();
       
    55   img.src = preload[i];
       
    56 }
       
    57 
       
    58 function offline_mode_on()
       
    59 {
       
    60   unsetAjaxLoading();
       
    61   document.getElementById('offlinemode').style.display = 'block';
       
    62   offline_mode = true;
       
    63 }
       
    64 
       
    65 function offline_mode_off()
       
    66 {
       
    67   document.getElementById('offlinemode').style.display = 'none';
       
    68   offline_mode = false;
       
    69 }
       
    70 
       
    71 function verify_online()
       
    72 {
       
    73   if ( !offline_mode )
       
    74     return true;
       
    75   
       
    76   flash_offline();
       
    77   return false;
       
    78 }
       
    79 
       
    80 function flash_offline()
       
    81 {
       
    82   if ( document.getElementById('offlinebox') )
       
    83     return false;
       
    84   
       
    85   var box = document.createElement('div');
       
    86   $(box)
       
    87     .css('position', 'absolute')
       
    88     .css('padding', '50px 80px')
       
    89     .css('background-image', 'url(/trans80.png)')
       
    90     .css('color', 'black')
       
    91     .css('text-align', 'center')
       
    92     .attr('id', 'offlinebox')
       
    93     .opacity(0);
       
    94   
       
    95   var image = document.createElement('img');
       
    96   image.src = '/offlinemodelarge.png';
       
    97   box.appendChild(image);
       
    98   
       
    99   document.body.appendChild(box);
       
   100   
       
   101   $(box)
       
   102     .css('top',  (( getHeight() / 2 ) - ( $(box).Height() / 2 ) + getScrollOffset()) + 'px')
       
   103     .css('left', (( $(document.body).Width() / 2 ) - ( $(box).Width() / 2 )) + 'px');
       
   104   
       
   105   $(box).fadeIn(250);
       
   106   window.setTimeout(function()
       
   107     {
       
   108       $(box).fadeOut(250);
       
   109       window.setTimeout(function()
       
   110         {
       
   111           document.body.removeChild(box);
       
   112         }, 250);
       
   113     }, 1000);
       
   114 }
       
   115 
    50 function ajaxGet(uri, f)
   116 function ajaxGet(uri, f)
    51 {
   117 {
    52   if ( ajax_panicked )
       
    53     return false;
       
    54   
       
    55   if (window.XMLHttpRequest)
   118   if (window.XMLHttpRequest)
    56   {
   119   {
    57     ajax = new XMLHttpRequest();
   120     ajax = new XMLHttpRequest();
    58   }
   121   }
    59   else
   122   else
    73   ajax.send(null);
   136   ajax.send(null);
    74 }
   137 }
    75 
   138 
    76 function ajaxPost(uri, parms, f)
   139 function ajaxPost(uri, parms, f)
    77 {
   140 {
    78   if ( ajax_panicked )
       
    79     return false;
       
    80   
       
    81   if (window.XMLHttpRequest)
   141   if (window.XMLHttpRequest)
    82   {
   142   {
    83     ajax = new XMLHttpRequest();
   143     ajax = new XMLHttpRequest();
    84   }
   144   }
    85   else
   145   else
   125 var refresh_playlist = function()
   185 var refresh_playlist = function()
   126 {
   186 {
   127   setAjaxLoading();
   187   setAjaxLoading();
   128   ajaxGet('/action.json/refresh', function()
   188   ajaxGet('/action.json/refresh', function()
   129     {
   189     {
   130       if ( ajax.readyState == 4 && ajax.status == 200 )
   190       if ( ajax.readyState == 4 && ajax.status == 200 && ( (window.location.hash != '#offlinemode' && !first_load ) || first_load ) )
   131       {
   191       {
       
   192         offline_mode_off();
   132         unsetAjaxLoading();
   193         unsetAjaxLoading();
   133         var response = (' ' + ajax.responseText).substr(1);
   194         var response = (' ' + ajax.responseText).substr(1);
   134         // quickie JSON parser :)
   195         // quickie JSON parser :)
   135         response = eval('(' + response + ')');
   196         response = eval('(' + response + ')');
   136         // has the playlist been modified?
   197         // has the playlist been modified?
   142             window.location.reload();
   203             window.location.reload();
   143             return false;
   204             return false;
   144           }
   205           }
   145         }
   206         }
   146         playlist_md5 = response.playlist_hash;
   207         playlist_md5 = response.playlist_hash;
   147         // update track number
       
   148         if ( response.current_track != current_track )
       
   149         {
       
   150           var ot_id = 'track_' + current_track;
       
   151           var nt_id = 'track_' + response.current_track;
       
   152           current_track = response.current_track;
       
   153           if ( $(ot_id).hasClass('current') )
       
   154           {
       
   155             $(ot_id).rmClass('current');
       
   156           }
       
   157           if ( ! $(nt_id).hasClass('current') )
       
   158           {
       
   159             $(nt_id).addClass('current');
       
   160           }
       
   161           pulsar_reset();
       
   162         }
       
   163         // update playing status
       
   164         is_playing = response.is_playing;
       
   165         if ( allow_control )
       
   166         {
       
   167           var img = $('btn_playpause').object.getElementsByTagName('img')[0];
       
   168           if ( is_playing )
       
   169           {
       
   170             img.src = img_pause;
       
   171           }
       
   172           else
       
   173           {
       
   174             img.src = img_play;
       
   175           }
       
   176         }
       
   177         // update volume
       
   178         if ( response.volume != current_volume )
       
   179         {
       
   180           set_volume_fill(response.volume);
       
   181           current_volume = response.volume;
       
   182         }
       
   183         // auto-refresh on track advance
       
   184         if ( ct_advance_timeout )
       
   185         {
       
   186           clearTimeout(ct_advance_timeout);
       
   187         }
       
   188         // countdown/up timer
       
   189         var time_remaining = response.current_track_length - response.current_track_pos;
       
   190         current_track_length = response.current_track_length;
       
   191         current_track_pos = response.current_track_pos;
       
   192         if ( ct_counter )
       
   193           clearInterval(ct_counter);
       
   194         update_clock();
       
   195         
   208         
   196         // set page title
   209         update_timers(response);
   197         updateTitle(response.current_track_artist, response.current_track_album, response.current_track_title);
       
   198         
       
   199         // if not playing, set the position slider to zero
       
   200         if ( !is_playing && !response.is_paused )
       
   201         {
       
   202           posslide_set_position(0);
       
   203         }
       
   204         
       
   205         // set advance timer
       
   206         if ( is_playing && time_remaining > 0 )
       
   207         {
       
   208           ct_advance_timeout = setTimeout(refresh_playlist, ( 1000 * time_remaining ));
       
   209           ct_counter = setInterval(update_clock, 1000);
       
   210         }
       
   211         if ( first_load )
       
   212         {
       
   213           first_load = false;
       
   214           jump_current_track();
       
   215         }
       
   216       }
   210       }
   217       else if ( ajax.readyState == 4 && ajax.status != 200 )
   211       else if ( ajax.readyState == 4 && ( ajax.status != 200 || window.location.hash == '#offlinemode' ) )
   218       {
   212       {
   219         ajax_panic();
   213         if ( !offline_mode )
   220         console.debug(ajax);
   214           ajax_panic();
       
   215         else
       
   216           unsetAjaxLoading();
   221       }
   217       }
   222     });
   218     });
   223 }
   219 }
   224 
   220 
   225 var ajax_panicked = false;
   221 function update_timers(response)
       
   222 {
       
   223   // update track number
       
   224   if ( response.current_track != current_track )
       
   225   {
       
   226     var ot_id = 'track_' + current_track;
       
   227     var nt_id = 'track_' + response.current_track;
       
   228     current_track = response.current_track;
       
   229     if ( $(ot_id).hasClass('current') )
       
   230     {
       
   231       $(ot_id).rmClass('current');
       
   232     }
       
   233     if ( ! $(nt_id).hasClass('current') )
       
   234     {
       
   235       $(nt_id).addClass('current');
       
   236     }
       
   237     pulsar_reset();
       
   238   }
       
   239   // update playing status
       
   240   is_playing = response.is_playing;
       
   241   if ( allow_control )
       
   242   {
       
   243     var img = $('btn_playpause').object.getElementsByTagName('img')[0];
       
   244     if ( is_playing )
       
   245     {
       
   246       img.src = img_pause;
       
   247     }
       
   248     else
       
   249     {
       
   250       img.src = img_play;
       
   251     }
       
   252   }
       
   253   // update volume
       
   254   if ( response.volume != current_volume )
       
   255   {
       
   256     set_volume_fill(response.volume);
       
   257     current_volume = response.volume;
       
   258   }
       
   259   // auto-refresh on track advance
       
   260   if ( ct_advance_timeout )
       
   261   {
       
   262     clearTimeout(ct_advance_timeout);
       
   263   }
       
   264   // countdown/up timer
       
   265   var time_remaining = response.current_track_length - response.current_track_pos;
       
   266   current_track_length = response.current_track_length;
       
   267   current_track_pos = response.current_track_pos;
       
   268   if ( ct_counter )
       
   269     clearInterval(ct_counter);
       
   270   update_clock();
       
   271   
       
   272   // set page title
       
   273   updateTitle(response.current_track_artist, response.current_track_album, response.current_track_title);
       
   274   
       
   275   // if not playing, set the position slider to zero
       
   276   if ( !is_playing && !response.is_paused )
       
   277   {
       
   278     posslide_set_position(0);
       
   279   }
       
   280   
       
   281   // set advance timer
       
   282   if ( is_playing && time_remaining > 0 )
       
   283   {
       
   284     ct_advance_timeout = setTimeout(refresh_playlist, ( 1000 * time_remaining ));
       
   285     ct_counter = setInterval(update_clock, 1000);
       
   286   }
       
   287   if ( first_load )
       
   288   {
       
   289     first_load = false;
       
   290     if ( window.iPhone )
       
   291     {
       
   292       setTimeout('jump_current_track();', 1000);
       
   293     }
       
   294     else
       
   295     {
       
   296       jump_current_track();
       
   297     }
       
   298   }
       
   299 }
   226 
   300 
   227 function ajax_panic()
   301 function ajax_panic()
   228 {
   302 {
   229   // set error flag
   303   offline_mode_on();
   230   ajax_panicked = true;
       
   231   
       
   232   // scroll to the top
       
   233   window.scroll(0, 0);
       
   234   
       
   235   // stop events
       
   236   pulsar_reset();
       
   237   window.clearInterval(pl_refresh_id);
       
   238   if ( ct_counter )
       
   239     window.clearInterval(ct_counter);
       
   240   if ( pulsar_interval_id )
       
   241     window.clearInterval(pulsar_interval_id);
       
   242   
       
   243   // show error message
       
   244   var floater = document.createElement('div');
       
   245   floater.style.backgroundColor = '#ffffff';
       
   246   floater.style.opacity = 0.7;
       
   247   floater.style.filter = 'alpha(opacity=70)';
       
   248   floater.style.textAlign = 'center';
       
   249   floater.style.paddingTop = '120px';
       
   250   floater.style.position = 'fixed';
       
   251   floater.style.zIndex = '999';
       
   252   floater.style.width = '100%';
       
   253   floater.style.height = '100%';
       
   254   floater.style.top = '0px';
       
   255   floater.style.left = '0px';
       
   256   floater.style.color = '#000000';
       
   257   floater.innerHTML = 'There was a problem with a refresh request to the server. Please reload the page.';
       
   258   var body = document.getElementsByTagName('body')[0];
       
   259   body.appendChild(floater);
       
   260 }
   304 }
   261 
   305 
   262 function player_action(action)
   306 function player_action(action)
   263 {
   307 {
       
   308   if ( !verify_online() )
       
   309   {
       
   310     return false;
       
   311   }
       
   312   
   264   var act2 = action;
   313   var act2 = action;
   265   setAjaxLoading();
   314   setAjaxLoading();
   266   ajaxGet('/action.json/' + action, function()
   315   ajaxGet('/action.json/' + action, function()
   267     {
   316     {
   268       if ( ajax.readyState == 4 && ajax.status == 200 )
   317       if ( ajax.readyState == 4 && ajax.status == 200 )
   273     });
   322     });
   274 }
   323 }
   275 
   324 
   276 function jump_to_song(tid)
   325 function jump_to_song(tid)
   277 {
   326 {
       
   327   if ( !verify_online() )
       
   328   {
       
   329     return false;
       
   330   }
       
   331   
   278   setAjaxLoading();
   332   setAjaxLoading();
   279   if ( tid == current_track )
   333   if ( tid == current_track )
   280     return false;
   334     return false;
   281   if ( !allow_control )
   335   if ( !allow_control )
   282     return false;
   336     return false;
   343         update_clock();
   397         update_clock();
   344       }
   398       }
   345     });
   399     });
   346 }
   400 }
   347 
   401 
       
   402 function offline_advance_track()
       
   403 {
       
   404   var new_track = current_track + 1;
       
   405   if ( !document.getElementById('track_' + new_track) )
       
   406     new_track = 0;
       
   407   
       
   408   update_timers({
       
   409     is_playing: is_playing,
       
   410     is_paused: false,
       
   411     volume: current_volume,
       
   412     current_track: new_track,
       
   413     current_track_length: document.getElementById('track_' + new_track).getAttribute('amarok:length_sec'),
       
   414     current_track_pos: 0,
       
   415     current_track_artist: 'FIXME artist',
       
   416     current_track_album: 'FIXME album',
       
   417     current_track_title: 'FIXME title'
       
   418   })
       
   419 }
       
   420 
   348 function update_clock()
   421 function update_clock()
   349 {
   422 {
       
   423   if ( offline_mode && current_track_pos > current_track_length )
       
   424   {
       
   425     offline_advance_track();
       
   426   }
       
   427   
   350   posslide_set_position((100 * (current_track_pos / current_track_length)));
   428   posslide_set_position((100 * (current_track_pos / current_track_length)));
   351   var str = secs_to_string(current_track_pos) + '/' + secs_to_string(current_track_length);
   429   var str = secs_to_string(current_track_pos) + '/' + secs_to_string(current_track_length);
   352   $('playmeter').object.innerHTML = str;
   430   $('playmeter').object.innerHTML = str;
   353   current_track_pos++;
   431   current_track_pos++;
   354 }
   432 }